То, что вы видите, это вызвано тем, что реальные цифры (читать с плавающей точкой) не может быть выражено с совершенным точность и точность в двоичных компьютерах. Это факт жизни. Вместо этого компьютеры приближают значение и сохраняют его в памяти в определенном формате.
В случае большинства современных машин (включая любую машину, на которой работает MSVC Express) этот формат равен IEEE 754.
Короче говоря, это то, как действительные числа хранятся в IEEE 754: есть один знаковый бит, 8 бит экспоненты и 23 бита фракции (для типа float
данных - doubles
использовать больше битов, соответственно, но формат тот же самый). Из-за этого вы никогда не сможете достичь совершенной точности и точности. К счастью, вы можете достичь большой точности и точности практически для любого приложения, включая критические финансовые системы и научные системы.
Вам не нужно знать все, что нужно знать о IEEE754, чтобы иметь возможность использовать плавающие точки в коде. Но есть несколько вещей, которые вы должны знать:
1) Вы можете не сравнивайте 2 значения с плавающей точкой для равенства, из-за ошибками округления, присущих с плавающей точкой calulation & хранения. Вместо этого вы должны сделать что-то вроде этого:
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 цифр точности.
Добро пожаловать с плавающей точкой. – GManNickG
Этот вопрос (или варианты) возникает через несколько дней здесь. Определенно дубликат какого-то рода! – spender