У меня есть число с плавающей запятой, которое я хочу усечь до 3-х мест, но я не хочу округлять.
Например, преобразуйте 1.0155555555555555
в 1.015
(not 1.016
).
Как я буду делать это в Ruby?
У меня есть число с плавающей запятой, которое я хочу усечь до 3-х мест, но я не хочу округлять.
Например, преобразуйте 1.0155555555555555
в 1.015
(not 1.016
).
Как я буду делать это в Ruby?
Предполагая, что у вас есть float
, попробуйте следующее:
(x * 1000).floor / 1000.0
Результат:
1.015
Посмотрите, как он работает в Интернете: ideone
Вы также можете преобразовать в BigDecimal и вызвать усечение на нем.
1.237.to_d.truncate(2).to_f # will return 1.23
Поскольку ruby 2.4 Float#truncate
метод принимает в качестве необязательного аргумента количество десятичных цифр:
1.0155555555555555.truncate(3)
# => 1.015
Умножьте на тысячу, пол, разделите на тысячу, сделав так, чтобы сделать плавающее деление.
(x * 1000).floor / 1000.0
Или, в Ruby 1.9.2, используя версию раунда, которая недоступна в более ранних версиях,
(x - 0.0005).round(3)
Ответ sid прекрасен, но он пропускает первое требование и, таким образом, терпит неудачу в тесте Anwar. требование есть, мы должны начать работать так, чтобы ruby не конвертировал число с готовностью. и запустить raw, поскольку raw gets - использовать обычную строку, поэтому
> "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
просто поделись этим сейчас, так как я сам столкнулся с этой проблемой сегодня:)
Это решение основано на блестящем трюке BigDecimal от @SidKrishnan, но также может обрабатывать большие поплавки, не прерывая точность проблем.
# 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
Вы можете сделать это с помощью регулярного выражения, так как рубины/рельсы имеют предел точности.
- сначала преобразовать число в строку, а затем сделать следующее -
input = "114.99999999999999999999"
вход [/\ D +.\Д/]
114.99