gpt4 book ai didi

ruby - 为什么 Ruby 的 Rational 类将字符串参数与数字参数区别对待?

转载 作者:数据小太阳 更新时间:2023-10-29 09:03:08 26 4
gpt4 key购买 nike

我正在使用 ruby​​ 的 Rational 库将图像的宽度和高度转换为纵横比。

我注意到字符串参数与数字参数的处理方式不同。

>> Rational('1.91','1')
=> (191/100)
>> Rational(1.91,1)
=> (8601875288277647/4503599627370496)

>> RUBY_VERSION
=> "2.1.5"
>> RUBY_ENGINE
=> "ruby"

仅供引用 1.91:1 是 Facebook 为其平台上的图片推荐的纵横比。

像 191 和 100 这样的值比 8601875288277647 和 4503599627370496 更方便地存储在我的数据库中。但是我想在决定使用哪种方法之前了解这种差异的来源。

The Rational test suite似乎没有涵盖这个确切的案例。

最佳答案

免责声明:这只是一个有根据的猜测,基于对如何实现这一壮举的一些了解。

正如 Kent Dahl 所说, float 并不精确,它们具有固定的精度,这意味着 1.91 实际上是 1.910000000000000000001 或类似的东西,ruby“知道”应该显示为 1.91。

另一方面,“1.91”是一个字符串,基本上是一个字符数组:'1'、'.'、'9'、'1'。

这就是说,这是你需要做的,从 float 中构建理性:

  1. 摆脱 . (在数学上,将分子和分母乘以 10^x,或乘以 10,因为 . 后面有数字。)
  2. 找到最大公分母 (gcd)
  3. 用gcd除以num和denom

然而,第 1 步对于 Float 和 String 有点不同:

  • float ,我们将不得不乘以 10^x,其中 x(因为精度)不是 2(正如人们认为的 1.91),而是更多的东西,比如 16(记住:1.9100...1) .
  • 对于字符串,我们可以将其转换为 float 并执行相同的技巧,但是嘿,还有一个更简单的方法:我们只需计算点后面的字符数(即 2),删除点并乘以10^2 的 denom... 这不仅更简单,而且更精确。

当应用第 3 步时,大数字可能会再次消失,这就是为什么在处理 float 的有理数时,您不会总是得到那些奇怪的结果。

TLDR:数字将根据参数为 String 或 FLoat 以不同方式构建。 FLoats 可以产生很长的数字,因为精度。

关于ruby - 为什么 Ruby 的 Rational 类将字符串参数与数字参数区别对待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30515051/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com