То, что вы видите, вызвано тем фактом, что действительные числа (с плавающей запятой) не могут быть выражены с идеальной точностью и точностью в двоичных компьютерах. Это факт жизни. Вместо этого компьютеры приближают значение и сохраняют его в памяти в определенном формате.
В случае большинства современных машин (включая любые машины, на которых работает MSVC Express), этот формат будет IEEE 754 .
Короче говоря, вот как реальные числа хранятся в IEEE 754: один бит знака, 8 битов экспоненты и 23 бита дроби (для float
тип данных - doubles
соответственно используют больше битов, но формат та же). Из-за этого вы никогда не сможете достичь идеальной точности и точности. К счастью, вы можете достичь высокой точности и точности практически для любого приложения, включая критические финансовые системы и научные системы.
Вам не нужно знать все, что нужно знать о IEEE754, чтобы использовать плавающие точки в вашем коде. Но есть несколько вещей, которые вы должны знать:
1) Вы никогда не сможете сравнить 2 значения с плавающей точкой на равенство из-за ошибки округления, присущей вычислению и хранению с плавающей точкой. Вместо этого вы должны сделать что-то вроде этого:
double d = 0.2;
double compare = 0.000000001;
double d2 = something;
if( (d - d2 < compare) && (d2 - d < compare) )
{
// numbers are equal
}
2) Составление ошибок округления. Чем больше раз вы выполняете операции со значением с плавающей запятой, тем больше потеря точности.
3) Вы не можете добавить две плавающие точки совершенно разной величины. Например, вы не можете добавить 1,5x10 ^ 30 и 1,5x10 ^ -30 и ожидать 60 цифр точности.