您好我是Scala的新手,以下行为真的很奇怪。即使是这个简单的计算,Scala也犯了错误吗?或者我做错了什么? 谢谢,
scala $ Welcome to Scala 2.12.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_111).
Type in expressions for evaluation. Or try :help.
scala> val radius:Double = 10.2
radius: Double = 10.2
scala> radius * 10
res0: Double = 102.0
scala> radius * 100
res1: Double = 1019.9999999999999
scala> radius * 1000
res2: Double = 10200.0
答案 0 :(得分:2)
Scala中的Double
是64位IEEE-754浮点数,相当于Java的双基元类型,如Scala's doc中所述。
floating point number的性质,Double
不一定返回数字的确切值。归结为小数不能总是精确地表示为二进制。
为了获得更好的精确度,您可能需要考虑使用BigDecimal。
答案 1 :(得分:0)
实数由Float(32位)和Double(64位)表示。这些是二进制格式,仅代表完整的实数范围。实数包括所有Rationals(可数无限)和Irrationals(无数无限)。 Double最多只能代表Rational的一个小的,有限的子集。
IEEE-754双精度浮点编码使用53位尾数(显式存储52位),11位指数和1位符号。阅读IEEE双精度浮点here。
可以精确表示的整数范围是+/- 2 ^ 53-1,而指数表示10 ^ + / - 308的范围。
您无法在| x |处精确表示整数x > 2 ^ 53
你不能精确地表达不是k / 2 ^ n形式的分数,其中k,n是整数(并且k,n在上述范围内)。因此,您不能代表1 / 3,1 / 5,1 / 7,1 / 11等
分母相对于2的素数的任何有理分数都无法准确表示。任何分数k / P,其中P是2以外的素数的乘积,k不是P的倍数,不能用IEEE-754浮点精确表示。
您正在观察的行为是由于近似表示1/5,并且从内部双/浮点表示到字符表示的转换执行舍入到某种精度。所有使用机器浮点(双/浮点)的语言都表现出类似的行为,但是从浮点数转换为打印的例程可能会以不同的方式舍入这些近似数字。
由于Cantor's proof的实数是uncountable且有理数是countable,几乎所有的实数都是不合理的。