2012-03-21 4 views
2

Я пишу код в C++ и определил PI как:с плавающей точкой округления

const double MathConstants::PI = atan(1.0)*4.0; 

Else, где в моем коде я установил переменный с плавающей точкой:

float result = (float) (-MathConstants::PI/2.0); 

При печати значения я получаю DB 0F C9 BF немного endian. Преобразован в большой endian, который является BF C9 0F DB.

Согласно http://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html, что эквивалентно -1.5707964.

Я не понимаю, почему я получаю -1.5707964 вместо -1.5707963. -1.5707963 - результат, которого я ожидаю, поскольку -PI/2 - -1.5707963267948966.

Может кто-нибудь просветить меня здесь?

+0

Не забывайте, что с плавающей запятой обычно находится в двоичной форме ... не десятичной. – Mysticial

+1

Сколько раз мы должны переходить через неотъемлемую погрешность значений с плавающей запятой? Кажется, это обсуждалось со смертью в StackOverflow. – dreamlax

+2

@dreamlax, если у людей есть 10 пальцев, мы продолжим получать эти вопросы. По крайней мере, это немного отличается от большинства других. –

ответ

4

Округление двоичное, а не десятичное. Когда вы смотрите на результат в десятичной системе, это кажется неправильным, потому что вы ожидаете, что он округлит окончательную десятичную цифру, но это не то, что он делает. Это округление финального бинарного бита.

Я набрал 1.57079632679489661923132169163975 как константу для PI/2 в указанную вами ссылку, и дал правильный результат 1.5707964.

Сравните 64-битное представление в 32-битовом представлении:

1 .1001001000011111101101010100010001000010110100011000 
1 .10010010000111111011011 

Та часть, которая была отрезана началась с 1, так что надлежащее округление требуется 32-битный результат, чтобы быть увеличено до.

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