-1

I'm not able to do an add on long type.

scala or the processor doesn't manage correctly the sign

scala> var i="-1014570924054025346".toLong
i: Long = -1014570924054025346

scala> i=i+92233720368547758L
i: Long = -922337203685477588
scala> var i=9223372036854775807L
i: Long = 9223372036854775807

scala> i=i+5
i: Long = -9223372036854775804

The first test where a negative number doesn't pass to a positive one is a problem for me

jean-luc T
  • 51
  • 1
  • 7

2 Answers2

2

I have not fully understood the question, but for the first example, you get the expected result. What happens in the second example, the Long number happens to be the maximum value for a Long (i.e Long.MaxValue) so essentially when you had another positive number, it's overflowing:

scala> Long.MaxValue
res4: Long = 9223372036854775807L

scala> Long.MaxValue + 1
res7: Long = -9223372036854775808L // which is Long.MinValue

scala> Long.MinValue + 4
res8: Long = -9223372036854775804L // which is the result that you get

In other words:

9223372036854775807L + 5 

is equivalent to:

Long.MaxValue + 5 

which is equivalent to:

Long.MinValue + 4 // because (Long.MaxValue + 1) = Long.MinValue

which is equals to -9223372036854775804L

Valy Dia
  • 2,781
  • 2
  • 12
  • 32
1

If you really need to use such big numbers, you might try using BigInt

scala> val x = BigInt(Long.MaxValue)
x: scala.math.BigInt = 9223372036854775807

scala> x + 1
res6: scala.math.BigInt = 9223372036854775808

scala> x + 5
res11: scala.math.BigInt = 9223372036854775812

scala> x + 10
res8: scala.math.BigInt = 9223372036854775817

scala> x * 1000
res10: scala.math.BigInt = 9223372036854775807000

scala> x * x
res9: scala.math.BigInt = 85070591730234615847396907784232501249

scala> x * x * x * x
res13: scala.math.BigInt = 7237005577332262210834635695349653859421902880380109739573089701262786560001

scala> 

The documentation on BigInt is rather, err, small. However, i believe that it is basically an infinite precision integer (can support as many digits as you need). Having said that, there will probably at some point be a limit. There is a comment on BigDecimal - which has more documentation - that at about 4,934 digits there might be some deviation between BigDecimal and BigInt.

I will leave it to someone else to work out whether or not x ^ 4 is the value shown above.

Oh, I almost forgot your negative number test, I aligned the sum with the initialisation, to make it easier to visualise that the result appears to be correct:

scala> val x =    BigInt("-1014570924054025346")
x: scala.math.BigInt    = -1014570924054025346
scala>                   x + 92233720368547758L
res15: scala.math.BigInt = -922337203685477588

scala> 

As for Ints, Longs and similar data types, they are limited in their size due to the number of bits they are constrained to. Int's are typically 32 bit and longs are typically 64 bits.

It is easier to visualise when you look at them in hexadecimal. A signed Byte (at 8 bits) has a maximum positive value of 0x7F (127). When you add one to it, you get 0x80 (-128). This is because we use the "Most Significant Bit" as an indicator of whether the number is positive or negative.

If the same byte was interpreted as unsigned, then 0x7F (127) would still become 0x80 when 1 is added to it. However, since we are interpreting it as unsigned, this would be equivalent to 128. We can keep adding one until we get to 0xFF (255) at which point if we add another 1 we will end up at 0x00 again which is of course 0.

Here are some references that explain this in much more detail:

Wikipedia - Twos complement

Cornell University - what is twos complement

Stack Overflow - what is 2s complement

GMc
  • 1,764
  • 1
  • 8
  • 26