Подтвердить что ты не робот

Усечение числа с плавающей запятой без округления

У меня есть число с плавающей запятой, которое я хочу усечь до 3-х мест, но я не хочу округлять.

Например, преобразуйте 1.0155555555555555 в 1.015 (not 1.016).

Как я буду делать это в Ruby?

4b9b3361

Ответ 1

Предполагая, что у вас есть float, попробуйте следующее:

(x * 1000).floor / 1000.0

Результат:

1.015

Посмотрите, как он работает в Интернете: ideone

Ответ 2

Вы также можете преобразовать в BigDecimal и вызвать усечение на нем.

1.237.to_d.truncate(2).to_f # will return 1.23

Ответ 3

Поскольку ruby 2.4 Float#truncate метод принимает в качестве необязательного аргумента количество десятичных цифр:

1.0155555555555555.truncate(3)
# => 1.015

Ответ 4

Умножьте на тысячу, пол, разделите на тысячу, сделав так, чтобы сделать плавающее деление.

(x * 1000).floor / 1000.0

Или, в Ruby 1.9.2, используя версию раунда, которая недоступна в более ранних версиях,

(x - 0.0005).round(3)

Ответ 5

Ответ 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

просто поделись этим сейчас, так как я сам столкнулся с этой проблемой сегодня:)

Ответ 6

Это решение основано на блестящем трюке 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

Ответ 7

Я видел более "вычислительный" способ сделать это не в ответах. Вы можете рассмотреть возможность использования метода ниже.

Это также будет работать в других языках программирования, таких как C/Java/Python и т.д. (Однако синтаксис приведения будет другим).

q = 1.0155555555555555
(q * 1000).to_i / 1000.0
=> 1.015

Ответ 8

Вы можете сделать это с помощью регулярного выражения, так как рубины/рельсы имеют предел точности.

- сначала преобразовать число в строку, а затем сделать следующее -

input = "114.99999999999999999999"

вход [/\ D +.\Д/]

114.99