我有一个浮点数,想将其截断为三个小数位,但不想进行四舍五入。
例如,将 1.0155555555555555
转换为 1.015
(而不是 1.016
)。
我该如何在Ruby中实现此功能?
我有一个浮点数,想将其截断为三个小数位,但不想进行四舍五入。
例如,将 1.0155555555555555
转换为 1.015
(而不是 1.016
)。
我该如何在Ruby中实现此功能?
您也可以将其转换为BigDecimal,然后对其进行截断。
1.237.to_d.truncate(2).to_f # will return 1.23
59.99999999999999999999.to_d.truncate(2).to_f
失败,返回 60.0
!! - Anwar59.99999999999999999999.inspect
也会被转化为"60.0"。因此,在to_d
之前进行了转换。 - Alex Fortuna111111111.9999999.to_d.truncate(2).to_f
是 111111112.0
。请看下面我修改过的版本。干杯! - Alex Fortuna自从 ruby 2.4 版本以来,Float#truncate
方法接受一个可选参数表示要保留的小数位数:
1.0155555555555555.truncate(3)
# => 1.015
(x * 1000).floor / 1000.0
(x - 0.0005).round(3)
sid的回答很好,但它错过了第一个要求,因此未能通过Anwar的测试。该要求是我们必须从原始状态开始,以便Ruby不会轻易地转换数字。而要像原始字符串一样开始,就要使用普通字符串,所以
> "59.99999999999999999999".to_d.truncate(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
你可以使用正则表达式来实现,因为 Ruby/Rails 有精度限制。
-- 首先将数字转换为字符串,然后执行以下操作 --
input = "114.99999999999999999999"
input[/\d+.\d/]
114.99