2010-09-23 6 views
8
double a = 18.565 
return Math.Round(a,2) 

..подтверждения 18.57.
Для каждого другого номера я попробовал округление банкира, как и ожидалось, например, Math.Round (2.565,2) вернул 2.56.Ошибка округления банкира C#

Любые подсказки, почему и когда это происходит? Является ли ошибка или я что-то пропущу о округлении банкира?

Спасибо ..

+0

Возможный дубликат [Получение другого результата в Math.Round] (http://stackoverflow.com/questions/1606664/getting-different-result-in-math-round) – Joren

ответ

16

Как сказал Матфей, ​​текст 18.565 не может быть точно представлен. Используемое значение - 18.565000000000001278976924368180334568023681640625 (найдено по DoubleConverter), что явно выходит за пределы поля. Теперь у меня есть тайное чувство, что иногдаMath.Round рассмотрит значение, которое составляет на самом деле за пределами полуострова, но которое находится как можно ближе к полуострове, которое может быть точно представлено, как точно at это пункт. Однако я не видел никакой документации, описывающей ситуации, в которой это применяется, и, очевидно, это не происходит в этом случае. Я не хотел бы полагаться на это.

Даже округленное значение не совсем точно 18.57. Это на самом деле 18.57000000000000028421709430404007434844970703125.

Принципиально, если вы действительно заботитесь о значении десятичных значений, вы должны использовать decimal. Это не только с точки зрения Math.Round - это относится ко всем аспектам обработки значений с плавающей запятой.

Это делает дать правильное значение для Math.Round, конечно:

decimal m = 18.565m; 
Console.WriteLine(Math.Round(m, 2)); // Prints 18.56 
+0

@Sam: Будет, спасибо :) –

+0

Хм, хорошо, это было первое, что я подумал, и проверил в каком-то онлайн-конверторе (http://babbage.cs.qc.edu/IEEE-754/Decimal.html). Конечно, не обращал особого внимания на то, что только первые что-то десятичные знаки видны, все нули. Эх, спасибо :) – Damir

5

18.565 не может быть точно представлен как двойной. Таким образом, двоичное представление немного выше, поэтому оно округляется. Если вы используете десятичную цифру:

decimal a = 18.565m; 
return Math.Round(a,2) 

его можно точно представить, и у вас не будет этой проблемы.

1

Я думаю, что представление FP означает, что это на самом деле не отставая 5; опасности FP!

Это прекрасно работает, хотя:

 decimal a = 18.565M; // <===== decimal 
     var s = Math.Round(a, 2); 
0

Двойник значение с плавающей точкой, так что может быть, если вы пишете как 18.565, это на самом деле в чем-то памяти, как 18.56500000000000000000000000000000001, и, следовательно, это больше, чем середина ,

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