我有一个浮点数,我想截断到 3 位,但我不想四舍五入。
例如,将
1.0155555555555555
转换为 1.015
(而不是 1.016
)。
我该如何在 Ruby 中做到这一点?
您还可以转换为 BigDecimal,并对其调用 truncate。
1.237.to_d.truncate(2).to_f # will return 1.23
乘以千,取整,除以千,确保进行浮点除法。
(x * 1000).floor / 1000.0
或者,在 Ruby 1.9.2 中,使用早期版本中不可用的 round 版本,
(x - 0.0005).round(3)
sid 的答案很好,但它错过了第一个要求,因此未通过 Anwar 的测试。那里的要求是我们必须从原始开始,这样 ruby 就不会轻易转换数字。并且像原始获取一样开始原始是使用纯字符串,所以
> "59.99999999999999999999".to_d.截断(2) => #BigDecimal:55a38a23cd68,'0.5999E2',18(45)> > "59.99999999999999999999".to_d.truncate(2).to_s =>“59.99” > "59.99999999999999999999".to_d.truncate(2).to_f => 59.99
现在就分享这个,因为我今天自己也遇到了这个问题:)
该解决方案基于@SidKrishnan 的绝妙 BigDecimal 技巧,但也可以处理更大的浮点数,而不会在精度问题上出现问题。
# Truncate a floating-point value without rounding up.
#
# trunc_float(1.999, 2) # => 1.99
# trunc_float(1.999, 0) # => 1.0
#
# @param value [Float]
# @param precision [Integer]
# @return [Float]
def trunc_float(value, precision)
BigDecimal(value.to_s).truncate(precision).to_f
end
#--------------------------------------- Test
describe ".trunc_float" do
def call(*args)
trunc_float(*args)
end
it "generally works" do
[
[[1, 0], 1.0],
[[1.999, 4], 1.999],
[[1.999, 3], 1.999],
[[1.999, 2], 1.99],
[[1.999, 1], 1.9],
[[1.999, 0], 1.0],
[[111111111.9999999, 3], 111111111.999],
[[1508675846.650976, 6], 1508675846.650976],
].each do |input, expected|
output = call(*input)
expect([input, output]).to eq [input, expected]
end
end
end
我看到更“计算”的方式并不在答案中。您可以考虑使用下面的方法。
这也适用于其他编程语言,例如 C/Java/Python 等(但是转换语法会有所不同)。
q = 1.0155555555555555
(q * 1000).to_i / 1000.0
=> 1.015
您的选择很少 - 上面的答案中提到了其中一些,但不是全部。
您可以使用
.floor(n)
# Returns the largest number less than or equal to
# float with a precision of n digits decimal digits (default: 0).
# -> basically its rounding down the number
> 1.0155555555555555.floor(3)
1.015
您可以使用
.truncate(n)
# Returns float truncated to a precision
# of n digits decimal digits (default: 0).
> 1.0155555555555555.truncate(3)
=> 1.015
您可以使用
.round(n, :truncate)
(仅适用于BigDecimal
,不适用于float
)
> 1.0155555555555555.to_d.round(3, :truncate).to_f
=> 1.015
您可以使用正则表达式来完成此操作,因为 ruby/rails 有精度限制。
-- 首先将数字转换为字符串,然后执行以下操作 -
输入=“114.99999999999999999999”
输入[/\d+.\d/]
114.99