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 .
这里有一些参考资料可以更详细地解释这一点:
Cornell University - what is twos complement
Stack Overflow - what is 2s complement
我无法添加长类型。
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 .
这里有一些参考资料可以更详细地解释这一点:
Cornell University - what is twos complement
Stack Overflow - what is 2s complement