Как сохранить число с плавающей запятой в ruby

Поэтому я пробую код для преобразования чисел в строки. Однако я заметил, что в некоторых случаях он не сохраняет последние два десятичных знака. Например, я набираю 1.01 и 1.04 для добавления и получаю обратно 2.04. Если я наберу только 1,05, он сохранит число и вернет его точно. Я понимаю, что происходит, вещи округляются. Я не знаю, как предотвратить его округление. Должен ли я просто рассматривать отправку (1.01 + 1.04) себе только как один вход?

Предупреждение! Я еще не пробовал это, поэтому не знаю, поддерживается ли это:

 user_input = (1.04+1.01) #entry from user
 user_input = gets.to_f
 user_input.to_test_string

Что у меня есть до сих пор:

    class Float
     def to_test_string

      cents = self % 1
      dollars = self - cents
      cents = cents * 100

      text = "#{dollars.to_i.en.numwords} dollars and #{cents.to_i.en.numwords} cents"

      puts text
      text
     end
    end
  puts "Enter two great floating point numbers for adding"
  puts "First number"
  c = gets.to_f
  puts "Second number"
  d = gets.to_f
  e = c+d
  puts e.to_test_string
  puts "Enter a great floating number! Example 10.34"
  a = gets.to_f 
  puts a.to_test_string

Спасибо за помощь! Опубликуйте код, чтобы я мог попробовать!


person Matt    schedule 07.11.2010    source источник
comment
Являются ли en и numwords методами Ruby или чем-то из Rails ActiveSupport?   -  person Andrew Grimm    schedule 08.11.2010
comment
@ Эндрю Гримм, по моему честному мнению, этого не должно быть и никогда не будет в ядре или стандартной библиотеке Ruby.   -  person Nakilon    schedule 08.11.2010
comment
@Nakilon: я согласен. Я спрашивал только потому, что изначально вопрос был помечен только ruby, а не ruby-on-rails.   -  person Andrew Grimm    schedule 08.11.2010
comment
en и numwords взяты из жемчужины лингвистики. Чего я почему-то не вставил в свой код.   -  person Matt    schedule 08.11.2010
comment
Взгляните на жемчужину Money: money.rubyforge.org   -  person Lars Haugseth    schedule 08.11.2010


Ответы (3)


Прежде всего: никогда не используйте float для денег — Использовать число с плавающей запятой или десятичное число для расчета суммы приложения в долларах?

irb> x = 1.01 + 1.04
=> 2.05
irb> y = x % 1
=> 0.04999999999999982
irb> (y * 100).to_i
=> 4

Но если захотеть ОЧЕНЬ ОЧЕНЬ сильно:

irb> (y * 100).round.to_i
=> 5
person Nakilon    schedule 07.11.2010

$ python
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 1.04+1.01
2.0499999999999998

Прочитайте это: Что должен знать каждый специалист по информатике об арифметике с плавающей запятой

Кроме того, что сказал Накилон.

person Wodin    schedule 07.11.2010

Это не проблема руби или вашего кода (хотя вам нужно избавиться от .en.numwords); это проблема с двоичным представлением с плавающей запятой.

Вы должны использовать Fixnum или Bignum для представления валюты.

eg.

class Currency
    def initialize str
        unless str =~ /([0-9]+)\.([0-9]{2})/
            raise 'invalid currency string'
        end
        @cents = $1.to_i * 100 + $2.to_i
    end
end
person david4dev    schedule 07.11.2010