Компилятор какой используете? У меня на MinGW всё постоянно — и постоянно не дробная часть. Есть две возможные причины нестабильного поведения.
1. Флаги сопроцессора — какая-то библиотека Си их не выставляет в постоянное значение.
2. Неопределённое поведение
(uint32_t)var
в предпоследней строке. Число-то >10
16, а uint32 — это 4·10
9.
Тут вы множите число на 10, пока оно не станет целым. Если оно не точный double (а оно не точный), получается ситуёвина, когда младшие биты зависят от флагов сопроцессора, и неизвестно, сколько итераций проработает программа. В любом случае крайне мала вероятность, что будет нечто умещающееся в uint32_t. Таким образом, есть такие варианты обойти проблему.
1) Умножить сразу на 1e8, а затем обрезать нули.
2) Сконвертировать в uint64_t.
Преобразование в uint64_t даёт постоянные 28800000000000024.
Умножение на 1e8 (число подобрано такое, чтобы в uint32_t вмещалось)
var *= 1e8;
number = (uint64_t)var;
while (number % 10 == 0)
number /= 10;
даёт 288.
UPD. Сам я для преобразования дробного в строку в коммерческой проге использую собственную функцию, основанную на GRISU. Там есть много функций наподобие: точность 7 знаков, но если число <10
10 — выводим его как целое, с 9-ю знаками.