为什么编程语言同样限制 22/7 的精度?
Why are the programming languages limits precision of 22/7 equally?
我试过了
Erlang
$ erl
1> Pi = 22/7.
3.142857142857143
Haskell
$ ghci
Prelude> 22/7
3.142857142857143
Python
$ python
>>> 22/7.0
3.142857142857143
Ruby
$ irb
2.1.6 :001 > 22 / 7.0
=> 3.142857142857143
结果是一样的。为什么?
发生这种情况是因为所有语言都对非整数使用相同的数字表示形式:IEEE 754 floating point numbers 很可能具有相同的精度级别。 (32 位 "floats" 或 64 位 "doubles",具体取决于您的系统和语言的配置方式。)
浮点数是此类操作的默认选择,这在很大程度上是因为硬件直接支持它们。然而,从根本上说,没有什么能阻止语言也支持其他类型的数字。这在 Haskell 中最容易证明,它的标准库中有有理数:
λ> 22/7 :: Rational
22 % 7
有理数是分数,因此它存储为一对整数,除法时不会丢失任何精度。同时,有些运算比普通浮点数更难,效率更低。
另一种可能的表示形式是 fixed-point numbers,它的范围比浮点数小,但在 范围内可以更好地保持精度。 (我真的在这里挥舞着很多细节。)你也可以在 Haskell 中尝试这些:
λ> import Data.Fixed
λ> 22/7 :: Deci
3.1
λ> 22/7 :: Centi
3.14
λ> 22/7 :: Micro
3.142857
我试过了
Erlang
$ erl
1> Pi = 22/7.
3.142857142857143
Haskell
$ ghci
Prelude> 22/7
3.142857142857143
Python
$ python
>>> 22/7.0
3.142857142857143
Ruby
$ irb
2.1.6 :001 > 22 / 7.0
=> 3.142857142857143
结果是一样的。为什么?
发生这种情况是因为所有语言都对非整数使用相同的数字表示形式:IEEE 754 floating point numbers 很可能具有相同的精度级别。 (32 位 "floats" 或 64 位 "doubles",具体取决于您的系统和语言的配置方式。)
浮点数是此类操作的默认选择,这在很大程度上是因为硬件直接支持它们。然而,从根本上说,没有什么能阻止语言也支持其他类型的数字。这在 Haskell 中最容易证明,它的标准库中有有理数:
λ> 22/7 :: Rational
22 % 7
有理数是分数,因此它存储为一对整数,除法时不会丢失任何精度。同时,有些运算比普通浮点数更难,效率更低。
另一种可能的表示形式是 fixed-point numbers,它的范围比浮点数小,但在 范围内可以更好地保持精度。 (我真的在这里挥舞着很多细节。)你也可以在 Haskell 中尝试这些:
λ> import Data.Fixed
λ> 22/7 :: Deci
3.1
λ> 22/7 :: Centi
3.14
λ> 22/7 :: Micro
3.142857