Scala 不能在很长的时间内添加

scala can't make an add on a long

我无法添加长类型。

scala 或处理器没有正确管理标志

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

第一个负数不能传递给正数的测试对我来说是个问题

我没有完全理解这个问题,但是对于第一个例子,你得到了预期的结果。在第二个例子中发生了什么,Long 数字恰好是 Long 的最大值(即 Long.MaxValue),所以基本上当你有另一个正数时,它会溢出:

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

换句话说:

9223372036854775807L + 5 

相当于:

Long.MaxValue + 5 

相当于:

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

等于-9223372036854775804L

如果你真的需要使用这么大的数字,你可以尝试使用 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> 

关于 BigInt 的文档相当,呃,很小。但是,我相信它基本上是一个无限精度的整数(可以根据需要支持任意数量的数字)。话虽如此,在某个时候可能会有一个限制。 BigDecimal 上有一条评论——它有更多的文档——在大约 4,934 位数字处,BigDecimal 和 BigInt 之间可能存在一些偏差。

我会把它留给其他人来计算 x ^ 4 是否是上面显示的值。

哦,我差点忘了你的负数测试,我将总和与初始化对齐,以便更容易看到结果似乎是正确的:

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

scala> 

对于 Int、Long 和类似的数据类型,由于它们受限于位数,因此它们的大小受到限制。 Int 通常是 32 位,long 通常是 64 位。

当您以十六进制查看它们时,更容易形象化。 signed 字节(8 位)的最大正值为 0x7F (127)。当你向它加一时,你会得到 0x80 (-128)。这是因为我们使用 "Most Significant Bit" 作为数字是正数还是负数的指示符。

如果相同的字节被解释为unsigned,那么0x7F(127)加1后仍然会变成0x80。但是,由于我们将其解释为无符号,这相当于 128。我们可以继续加一直到达到 0xFF (255),此时如果我们再加 1,我们将再次以 0x00 结束,这当然是 0 .

这里有一些参考资料可以更详细地解释这一点:

Wikipedia - Twos complement

Cornell University - what is twos complement

Stack Overflow - what is 2s complement