SIP 15: How to unsigned integer values

1,336 views
Skip to first unread message

Heiko Seeberger

unread,
Sep 6, 2012, 3:24:11 PM9/6/12
to scala...@googlegroups.com
Hey,

Reading through SIP 15 I stumbled over "New numeric classes, such as unsigned ints. There would no longer need to be a boxing overhead for such classes. So this is similar to value classes in .NET". What's meant here? Transforming the range from 0 to 4294967295? If so, how would that work?

Thanks
Heiko

--

Heiko Seeberger
Twitter: @hseeberger
Company: Typesafe - The software stack for applications that scale
Author of "Durchstarten mit Scala, a tutorial-style Scala book"

Paul Phillips

unread,
Sep 6, 2012, 4:28:37 PM9/6/12
to scala...@googlegroups.com
On Thu, Sep 6, 2012 at 12:24 PM, Heiko Seeberger <heiko.s...@gmail.com> wrote:
Hey,

Reading through SIP 15 I stumbled over "New numeric classes, such as unsigned ints. There would no longer need to be a boxing overhead for such classes. So this is similar to value classes in .NET". What's meant here? Transforming the range from 0 to 4294967295? If so, how would that work?

% scala3
Welcome to Scala version 2.11.0-20120905-004841-4f9851d1fd (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_31).
Type in expressions to have them evaluated.
Type :help for more information.

scala> final case class UInt(val x: Int) extends AnyVal with Ordered[UInt] {
  def toLong = 0x00000000FFFFFFFFL & x
  def compare(other: UInt) = toLong compare other.toLong
  def +(other: UInt) = UInt((toLong + other.toLong).toInt)
  override def toString = toLong + "(u)"
}
defined class UInt

scala> implicit def mkUInt(x: Int) = new UInt(x)
wmkUInt: (x: Int)UInt

scala> def f(x: UInt, y: UInt) = println(s"$x < $y ? ${x < y}")
f: (x: UInt, y: UInt)Unit

scala> 1 << 30
res0: Int = 1073741824

scala> 1 << 31
res1: Int = -2147483648

scala> f(1 << 30, 1 << 31)
1073741824(u) < 2147483648(u) ? true

scala> UInt(1 << 30) + UInt(1 << 31)
res3: UInt = 3221225472(u)

scala> class A { def f(x: UInt, y: UInt) = x + y }
defined class A

scala> :javap -v A
Compiled from "<console>"
public class A extends java.lang.Object

...
public int f(int, int);
  Code:
   Stack=3, Locals=3, Args_size=3
   0: getstatic #13; //Field UInt$.MODULE$:LUInt$;
   3: iload_1
   4: iload_2
   5: invokevirtual #16; //Method UInt$.extension$$plus:(II)I
   8: ireturn
 
scala> :javap -v UInt$
...
public final long extension$toLong(int);
   0: ldc2_w  #57; //long 4294967295l
   3: iload_1
   4: i2l
   5: land
   6: lreturn

public final int extension$$plus(int, int);
   0: aload_0
   1: iload_1
   2: invokevirtual #70; //Method extension$toLong:(I)J
   5: aload_0
   6: iload_2
   7: invokevirtual #70; //Method extension$toLong:(I)J
   10:  ladd
   11:  l2i
   12:  ireturn

Erik Osheim

unread,
Sep 6, 2012, 4:34:00 PM9/6/12
to scala...@googlegroups.com
On Thu, Sep 06, 2012 at 09:24:11PM +0200, Heiko Seeberger wrote:
> Reading through SIP 15 I stumbled over "New numeric classes, such as
> unsigned ints. There would no longer need to be a boxing overhead for
> such classes. So this is similar to value classes in .NET". What's
> meant here? Transforming the range from 0 to 4294967295? If so, how
> would that work?

Attached is an example I threw together. I only tested it a bit in the
REPL, but I think it illustrates the idea well enough.

scala> val x = new Unsigned(1000)
x: Unsigned = 1000

scala> val y = 1000
y: Int = 1000

scala> x*x*x*x
res0: Unsigned = 3567587328

scala> y*y*y*y
res1: Int = -727379968

I haven't really tested how well these kind of unsigned numbers
currently perform (the extension methods aren't final and are resolved
via invokevirtual, which probably isn't ideal), but I can confirm that
in most normal cases they are not boxed.

Of course, once you want to use arrays you will need to work with the
underlying type (e.g. Int) or face serious boxing.

-- Erik

Unsigned.scala

Erik Osheim

unread,
Sep 6, 2012, 4:35:13 PM9/6/12
to scala...@googlegroups.com
On Thu, Sep 06, 2012 at 04:34:00PM -0400, Erik Osheim wrote:
> Attached is an example I threw together. I only tested it a bit in the
> REPL, but I think it illustrates the idea well enough.

Of course, Paul beat me to it (and had a better implementation of
toLong to boot)!

-- Erik

Som Snytt

unread,
Sep 6, 2012, 4:39:03 PM9/6/12
to scala...@googlegroups.com
If Typesafe opens an online store, I hope they carry t-shirts that say, "Paul beat me to it."

Another one I'd like, because I don't know where else to apply this slogan: "paulp fiction".

Sadache Aldrobi

unread,
Sep 6, 2012, 4:43:25 PM9/6/12
to scala...@googlegroups.com
On Thu, Sep 6, 2012 at 10:39 PM, Som Snytt <som....@gmail.com> wrote:
If Typesafe opens an online store, I hope they carry t-shirts that say, "Paul beat me to it."

Another one I'd like, because I don't know where else to apply this slogan: "paulp fiction".

I'd buy the latter.
 


On Thu, Sep 6, 2012 at 1:35 PM, Erik Osheim <er...@plastic-idolatry.com> wrote:
On Thu, Sep 06, 2012 at 04:34:00PM -0400, Erik Osheim wrote:
> Attached is an example I threw together. I only tested it a bit in the
> REPL, but I think it illustrates the idea well enough.

Of course, Paul beat me to it (and had a better implementation of
toLong to boot)!

-- Erik




--
www.sadekdrobi.com
ʎdoɹʇuǝ

martin odersky

unread,
Sep 6, 2012, 4:55:32 PM9/6/12
to scala...@googlegroups.com
For a complete implementation of UInt/ULong, including the tricky bit of how to do unsigned long division/remainder, see


Turning Uint into a value class is the last commit here:


I think indeed it would be promising to add this to the standard distribution.

Cheers

 - Martin


Rich Oliver

unread,
Oct 28, 2012, 9:02:40 AM10/28/12
to scala...@googlegroups.com
Am I right in saying that

val x: UInt = - 5

would still compile? Funnily I was just writing my own even Int class:

class IntEven(k: Int)    {
      val e = {require(k.isEven); k}     
  }
 implicit def IntEvenToInt(inp: IntEven): Int = inp.e

implicit class RichInt2(n: Int) extends Unchanged[Int]
   {
      override def unchanged: Int = n
      def isOdd: Boolean = if (n % 2 == 1) true else false
      def isEven: Boolean = if (n % 2 == 0) true else false
   }

I presume there's no way to implement IntEven as a value class
Reply all
Reply to author
Forward
0 new messages