首页 > 解决方案 > 如何在 ruby​​ on rails 中将浮点数渲染为分数

问题描述

我想构建一个帮助器,将浮点数显示为类似字符串的分数(编辑以删除我之前不准确的单词“方程式”)。

例如

12.25 

将会

12 1/4

我想我可以用一个噩梦般的条件语句链来构建它,但这似乎很混乱。似乎这应该存在于红宝石中,但我没有找到帮助者。

标签: ruby-on-railsruby

解决方案


你的问题不清楚。

首先,您需要了解浮点数是不精确的;它们具有离散的可表示值——例如,不可能0.1精确表示。

这是通常被错误标记的“错误”(在所有语言中,不仅仅是红宝石)的原因:

0.1 + 0.2 == 0.30000000000000004

其次,并非所有数字都是有理数。正如您所描述的,无法将 pi (3.14159 ...) 表示为分数。

第三,12 1/4不是等式。等式必须有等号。你所描述的似乎是一个混合数字

最后,您不能有定义不明确的要求,例如“我想将 0.33 表示为 1/3”——也就是说,您需要非常明确地说明应该应用哪些舍入规则(如果有)。0.33等于33/100,不是1/3。因此,出于此答案的目的,我将省略任何此类不明确的舍入。

这是您如何以编程方式尝试在 ruby​​ 中格式化混合数字

x = 12.25
puts "#{x.to_i} #{x.to_s.to_r - x.to_i}"
  # => "12 1/4"

或者,您可以这样做:

puts x.to_s.to_r.divmod(1).join(' ')
  # => "12 1/4"

注意使用to_s-- 这是非常有意的。没有它,您可能会得到“令人惊讶”(但技术上正确)的结果,例如:

0.1.to_r.divmod(1).join(' ')
  # => "0 3602879701896397/36028797018963968"

...这是因为,正如我在开始时所说,浮点数的精度有限。(数字 1/10 不能用二进制表示。)

如果您需要避免任何此类舍入错误(例如,如果您正在处理货币),您应该使用BigDecimal而不是Float. (或者也许Rational,在某些情况下。)


推荐阅读