我试图找出红宝石如何处理零分裂.Ruby根据类返回不同的结果.这是我试过的
0/0 # => ZeroDivisionError: divided by 0
1/0 # => ZeroDivisionError: divided by 0
1.0/0 # => Infinity
0.0/0.0 # => NaN
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?我不应该得到ZeroDivisionError所有上述案件吗?
更新 "无限"是标准数据类型吗?
(1.0/0).class # => Float
Run Code Online (Sandbox Code Playgroud)
Gen*_*ene 10
Ruby只跟踪IEEE 754浮点标准.那个维基百科页面在解释你所看到的内容方面并不错.许多现代语言采用相同的方法.
直观地说,你看到的行为非常有意义.一般来说,
1/<small number> = <big number>
Run Code Online (Sandbox Code Playgroud)
因此,在极限,
1/0 -> Infinity and similarly -1/0 -> -Infinity
Run Code Online (Sandbox Code Playgroud)
Infinity是浮点子系统理解的常量.另一方面
0 / <any non-zero> = 0
Run Code Online (Sandbox Code Playgroud)
所以我们在0/0上有冲突.它应该是零还是无穷大?IEEE标准答案是"非数字",NaN你看到的是另一个浮点常数.
常量NaN和正或负Infinity通过表达式传播也是有意义的.例如:
Infinity + <any (necessarly finite) number> = Infinity
Run Code Online (Sandbox Code Playgroud)
和
<any number> + NaN = NaN
Run Code Online (Sandbox Code Playgroud)
更有趣的是:
1 / Infinity = 0
Run Code Online (Sandbox Code Playgroud)
您可以尝试自己:
irb(main):005:0> 1.0 / (1.0 / 0.0)
=> 0.0
Run Code Online (Sandbox Code Playgroud)
通过这种方式,浮点计算即使在溢出或除以零的情况下也可以继续,并且仍能产生一个合理的信息答案(尽管在您了解标准井之后,您将看到依赖于答案通常是一个坏主意).
这远不是标准提供的唯一行为.其他人可以选择.但是Ruby会为你做这件事.源文件numeric.c,function Init_Numeric,设置主处理器,以便除零传播无穷大.其他语言可能会做出其他选择,例如生成异常.
关键是浮点数具有舍入误差。浮点数0.0不一定表示精确的零或数学意义上的0.0,而是代表将四舍五入到0.0给定精度的所有数字。精确地除以0并不是数学上定义的,但0.0如果除数的非零绝对值小到足以舍入,则除以除法有返回错误的危险0.0。您不希望当除数的绝对值不为零时,程序突然返回错误。如果是浮点数,让系统为除以0.0而不是禁止它。但是该数字无法以常规方式表示,因此将其分配为NaN或Infinity。对此产生误解的是,从数学意义上讲,无穷不是无限。它仅表示“比该系统中可以表示的任何其他数字大的数字”。这就解释了以下情况:
1.0/0.0 # => Infinity
0.0/0.0 # => NaN
Run Code Online (Sandbox Code Playgroud)
当to的一个参数/是float时,Ruby 将另一个参数强制转换为float,因此
1/0.0
1.0/0
Run Code Online (Sandbox Code Playgroud)
将与相同1.0/0.0。
另一方面,该整数0不包含错误,并且精确为零,因此没有这种危险。产生零除误差更有意义。那解释了
1/0 # => Error
0/0 # => Error
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3692 次 |
| 最近记录: |