Ваша первоначальная идея довольно близка, проблема в том, что с плавающей запятой выполняется округление, которое не дает точному результату.Вам нужно использовать порог вместо сравнения точно с 0,0, и вы должны разрешить, чтобы операция (int)
могла усекаться неправильно, и вам следует вместо этого округлять.Вы можете округлить, добавив 0,5 перед усечением.
Вы также столкнетесь с проблемой, когда количество цифр больше не будет соответствовать int
.Вы можете помочь, вычитая целую часть числа на каждом шаге.
Редактировать: Чтобы выбрать правильный порог, выберите максимальное количество десятичных знаков, которое вы хотите обработать.Если это 4, то наименьшее число, которое вы хотите вывести, равно 0.0001
.Сделайте свой порог половиной этого или 0.00005
.Теперь, каждый раз, когда вы умножаете свое число на 10, умножьте порог также на 10!
float threshold = 0.00005;
while (abs(*number - round(*number)) > threshold)
{
*number *= 10.0;
threshold *= 10.0;
// ...
}
Если ваш float и int 32-битные, вам не нужно беспокоиться о вычитании int.Возврат мантиссы будет сложнее.
Кроме того, предупреждение, которое я хотел дать вам раньше, но забыл: это работает только для положительных чисел.
Еще одно предупреждениедиапазон значений для float
довольно ограничен.Например, вы не сможете точно указать 1234.5670
, и в конце вы получите постороннюю цифру.Изменение на double
исправит это.