红宝石如何处理零分割?

ZX1*_*12R 11 ruby zero

我试图找出红宝石如何处理零分裂.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,设置主处理器,以便除零传播无穷大.其他语言可能会做出其他选择,例如生成异常.

  • 我建议在答案中包含实际信息,而不仅仅是链接. (7认同)
  • 但是,仅限链接的答案并不是很好.不要躲在后面"他们必须自己阅读整个事情,以便显示解释实际问题所需的两个句子." 相反,强调需要超越表面水平,*和*回答具体问题. (4认同)

fny*_*fny 7

浮点的行为反映了IEEE 754中的标准:

  • 无效操作(例如,负数的平方根)(默认情况下返回qNaN).
  • 除以零(对有限操作数的操作给出精确的无限结果,例如,1/0或log(0))(默认返回±无穷大).

对于整数除法实现运行时错误的决定在许多其他语言中也很常见,例如Java,C++,Python.Python实际上也调用了错误ZeroDivisionError.

有关这些分类和行为的原因,请参阅sawa的答案.


saw*_*awa 5

关键是浮点数具有舍入误差。浮点数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)