2009-11-30 3 views

ответ

0

Похож на простой случай binary floating point imprecision. На одной машине вы получаете 40.499999999, которая округляется до 40; на другом компьютере вы получаете 40.500000000001, который округляется до 41.

Если вам нужны точные цифры, вам не следует использовать двоичную с плавающей запятой. Вы можете использовать десятичную запятую или десятичную плавающую точку.

Редактировать: вы используете BigDecimal, вы говорите. Почему бы не избежать преобразования в float, используя #round, а затем #to_i? (Или #floor или #ceil вместо #round ... это не ясно, что ваша цель.)

b = BigDecimal.new("40.5") 
print b.round.to_i # => 41 
+0

Я сохранил пример очень просто, но это число действительно происходит из поля BigDecimal в базе данных. Я уверен, что проблема с плавающей запятой, о которой вы говорите, не совсем понятна, почему ее считают плавающей точкой. У вас по-прежнему возникает проблема: «% .0f»% BigDecimal («40.5») и «% .0d»% BigDecimal («40.5») – tsdbrown

+0

Это потому, что BigDecimals здесь преобразуются в float (через #to_f) перед тем, как перейти к операции форматирования. – ScottJ

+0

В случае, если это было не ясно, я отредактировал мой выше ответ, чтобы решить проблему с BigDecimal. – ScottJ

2

Как об использовании .round вместо этого? Rails даже улучшает его, так что вы можете указать точность (see API doc).

+0

Мы хотели сделать это в первую очередь, хотя 40.5.round (0) дает 41.0, что очень раздражает. Я вижу из API doc. Теперь теперь принимает nil, чтобы просто оставить 41 и no .0 после. Я уверен, что .round (nil) в версии rails, мы используем ошибки throw. Чтобы обойти это, мы округляем его сначала с помощью round (0), затем применяем строковый формат. Благодарю. – tsdbrown

+0

Я не понимаю комментарий tsdbrown. Float # round не принимает никаких аргументов. BigDecimal # round указывает, сколько десятичных знаков и ruby-doc.org не указывают ниль как юридический аргумент. Также BigDecimal не различает между 41.0 и 41. – ScottJ

1

ответ ScottJ не объясняет вашу проблему - 40,5 точно представима в двоичный файл. Что, вероятно, происходит так: Windows «printf» округляется наполовину вверх, и «printf» Ubuntu «округляет половину даже».

Смежные вопросы