问题
I have a floating point number that I want to truncate to 3 places but I don't want to round up.
For example, convert 1.0155555555555555
to 1.015
(not 1.016
).
How would I go about doing this in Ruby?
回答1:
Assuming you have a float
, try this:
(x * 1000).floor / 1000.0
Result:
1.015
See it working online: ideone
回答2:
You can also convert to a BigDecimal, and call truncate on it.
1.237.to_d.truncate(2).to_f # will return 1.23
回答3:
Since ruby 2.4 Float#truncate method takes as an optional argument a number of decimal digits:
1.0155555555555555.truncate(3)
# => 1.015
回答4:
Multiply by a thousand, floor, divide by a thousand, making sure to do a float division.
(x * 1000).floor / 1000.0
Or, in Ruby 1.9.2, using a version of round that wasn't available in earlier versions,
(x - 0.0005).round(3)
回答5:
sid's answer is fine but it misses the first requirement and thus fails Anwar's test. the requirement there is we must start raw so that ruby does not convert the number readily. and to start raw as raw gets is to use a plain string, so
> "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
just sharing this now, since i just encountered this problem myself today : )
回答6:
This solution is based on a brilliant BigDecimal trick by @SidKrishnan, but can also handle bigger floats without faltering on precision issues.
# 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
回答7:
I saw the more 'computational' way of doing this is not within the answers. You can consider using the method below.
This will also work in other programming languages, like C/ Java/ Python etc. (however the casting syntax would be different).
q = 1.0155555555555555
(q * 1000).to_i / 1000.0
=> 1.015
回答8:
You can do this using regex, since ruby/rails have precision limit.
-- first convert the number to string and then do following -
input = "114.99999999999999999999"
input[/\d+.\d/]
114.99
来源:https://stackoverflow.com/questions/8106677/truncate-a-floating-point-number-without-rounding-up