Деление поплавка на 10
Возможный дубликат:
Почему десятичные числа не могут быть представлены точно в двоичном формате?
Я разрабатываю довольно простой алгоритм использования математики под C++.
И у меня есть переменная с плавающей точкой с именем "step", каждый раз, когда я заканчиваю цикл while, мне нужно делить шаг на 10.
Так что мой код вроде этого,
float step = 1;
while ( ... ){
//the codes
step /= 10;
}
По моей глупой простой логике, это хорошо кончается. Шаг будет разделен на 10, от 1 до 0,1, от 0,1 до 0,01.
Но это не так, вместо этого появляется что-то вроде 0.100000000001. И я был как "Что, черт возьми"
Может кто-нибудь, пожалуйста, помогите мне с этим. Вероятно, это что-то в самом типе данных, которое я не совсем понимаю. Так что, если кто-то может объяснить дальше, это будет оценено.
2 ответа
Это численная проблема. Проблема в том, что 1/10 - это бесконечное длинное число в двоичном коде, и последующее применение деления на 10 заканчивается суммированием ошибки на каждом шаге. Чтобы получить более стабильную версию, вы должны умножить делитель. Но будьте осторожны: результат тоже не точный! Вы можете заменить поплавок на двойной, чтобы минимизировать ошибку.
unsigned int div = 1;
while(...)
{
double step = 1.0 / (double)div;
....
div *= 10;
}
Деление на десять не может быть точным для двоичной арифметики с плавающей запятой, поэтому вы видите результаты, которые будут немного отличаться от того, что вы ожидаете.
Двоичные числа с плавающей запятой представлены в виде целочисленного отношения, где знаменатель является степенью двойки. Поскольку ни одна двоичная дробь точно не равна одной десятой, вы увидите ближайшее представимое число вместо того, которое вы ожидали.