Я помню, как мой профессор CompSci говорил, что никогда не используйте поплавки для валюты.
Причина в том, что спецификация IEEE определяет значения с плавающей запятой в двоичном формате. По сути, он хранит знак, дробь и показатель степени для представления числа с плавающей точкой. Это как научная запись для двоичного кода (что-то вроде +1.43*10^2
). Из-за этого невозможно точно хранить дроби и десятичные дроби в Float.
Вот почему существует десятичный формат. Если вы сделаете это:
irb:001:0> "%.47f" % (1.0/10)
=> "0.10000000000000000555111512312578270211815834045" # not "0.1"!
тогда как если вы просто сделаете
irb:002:0> (1.0/10).to_s
=> "0.1" # the interprer rounds the number for you
Так что, если вы имеете дело с небольшими фракциями, например, сложными интересами или, может быть, даже с геолокацией, я очень рекомендую десятичный формат, поскольку в десятичном формате 1.0/10
равен точно 0,1.
Однако следует отметить, что, несмотря на меньшую точность, поплавки обрабатываются быстрее. Вот эталонный тест:
require "benchmark"
require "bigdecimal"
d = BigDecimal.new(3)
f = Float(3)
time_decimal = Benchmark.measure{ (1..10000000).each { |i| d * d } }
time_float = Benchmark.measure{ (1..10000000).each { |i| f * f } }
puts time_decimal
#=> 6.770960 seconds
puts time_float
#=> 0.988070 seconds
Ответ
Используйте float , когда вам не слишком важна точность. Например, для некоторых научных симуляций и расчетов требуется всего 3 или 4 значащих цифры. Это полезно в обмене на точность для скорости. Так как им нужна не столько точность, сколько скорость, они будут использовать float.
Используйте десятичное число , если вы имеете дело с числами, которые должны быть точными и суммировать до правильного числа (например, сложение процентов и связанных с деньгами вещей). Помните: если вам нужна точность, то вы всегда должны использовать десятичную дробь.