理解红宝石理性中的数字

时间:2011-05-07 16:56:55

标签: ruby math

来自http://www.ruby-doc.org/core/classes/Rational.html

Rational(10) / 3   #=> (10/3)
Rational(10) / 3.0 #=> 3.3333333333333335

Rational(-8) ** Rational(1, 3)
                  #=> (1.0000000000000002+1.7320508075688772i)

我理解前两个,但不是最后一个。请注意,Rational(8) ** Rational(1, 3)工作得很好,并且没有浮点上下文可以使水变得混乱。有人可以向我解释这个,以及如何得到-2就像我应该得到的那样?

编辑 :请注意,我并不是指如何在这个实例中获得-2,但是如何一般使用有理数检测复数表示是必要和适当地切换背景。

编辑#2 (感谢pst和Mat):根据pst的例子:

>> (Rational(-8) ** Rational(1,3)) ** Rational(3)
=> (-8.0+3.1086244689504383e-15i)

这是一个很好的例子,说明为什么我会尽可能地回复真实答案(如果这是Complex类吐出复数,我会更宽容,但这是Rational上课 - 我敢说它应该理性行事)。 Mat的答案说明了为什么人们可能想要一个通用的解决方案,比如Rationals(或复杂的类等)的猴子补丁或者包装类:因为否则我不能通过相对精确的处理基本数学运算的方式来懒惰。

我认为我在Mat的回复中看到了答案的根源,但是我不能立即明白如何将其转换为在通用代码中表现正常的猴子补丁或包装类。

3 个答案:

答案 0 :(得分:3)

答案不是-2:答案是2i糟糕,数学失败。在任何情况下,其余的部分仍然以某种方式相关。请参阅Mat的评论和Sawa的回答。

这并不能解释为什么输出中只有漂亮的2i(或(0+2i)),我怀疑它只是由于内部舍入错误(它没有' t尝试替换matlab)。 请参阅Sawa的答案,了解如何“理解”返回的复数的结果。

有关结果中使用的符号,请参阅Imaginary NumbersComplex Numbers

考虑:

>> (Rational(-8) ** Rational(1,3)) ** Rational(3)                       
=> (-8.0+3.1086244689504383e-15i)

那不远了!

然而,

>> (Rational(8) ** Rational(1,3)) ** Rational(3)                        
=> 8.0

“完美”。希望有人可以参与其中。

快乐的编码。


编辑,好的,这是发生的事情: Rational ** Rational的结果是不是一个Rational。

当结果为真Rational ** Rational -> Float时,但当结果包含虚数组件时,则为Rational ** Ration -> Complex

在“完美”的情况下,我们只是停留在Float准确度的范围内(至少足以获得“漂亮的结果”)。在导致Complex对象的情况下,由于存储在实部+虚部中,然后在数据上执行数学,因此组合部件的相对精度Float的界限不够好。

答案 1 :(得分:2)

最简单的方法是编写自己的根函数来查找真正的根,如果你想要的根是奇数,它会检查符号,然后恢复它。基本上:

(-8) ** (1/3) = -(8 ** 1/3)

我在另一种语言中遇到了类似的问题(参见here),其中一位成员给出了很好的解释原因。

答案 2 :(得分:2)

(1.0000000000000002+1.7320508075688772i)可能代表1+\sqrt{3}i,它是(正确的)答案之一:

(1+\sqrt{3}i)^3 = -8

它出了什么问题?

可能你忘了the fundamental theorem of algebra?根不是唯一的。但是,由于这种情况下的返回值是一个数字,因此必须有一些标准(可能来自ruby-internal算法)选择这个特定的标准。如果要选择其他根,则必须自己对该部分进行显式编码。一种方法是

-Rational(8) ** Rational(1, 3)
# => -2.0

但请注意,这仍然会给你一个浮动。那是因为,一旦你引入了分数幂,它就不再在有理数内闭合了。如果你仍然想要一个合理的答案2,你可能不得不使用至少可以求解多项式方程的软件。