12.32 не представляется в форматах, которые ваша реализация C использует для long double
или double
.
Ближайшее представимое значение до 12,32 в long double
может быть 12,319999999999999999722444243843710864894092082977294921875. Это частично объясняет, почему ваша программа показывает 3, 1, 9, 9, 9 и 9 - это действительные десятичные цифры числа.
Аналогично, ближайшим представимым значением 12,32 в double
может быть 12,32000000000000028421709430404007434844970703125, и это объясняет, почему ваша программа показывает 3, 2, 0, 0, 0 и 0.
Однако в показанном вами коде long double dec = 12.32;
, 12.32
является константой double
. Он должен иметь значение double
, даже если вы присваиваете ему значение long double
. Так что это не объясняет, почему ваша программа показывает 3, 1, 9, 9, 9 и 9. Вам потребуется суффикс l
, чтобы сделать его константой long double
, как в long double dec = 12.32l;
. Возможно, код, который вы показываете в вопросе, не совсем тот код, который вы использовали для создания 3, 1, 9, 9, 9 и 9.
Кроме того, код n *= 10;
не может использоваться для извлечения цифр. Это связано с тем, что в общем случае математический результат умножения значения double
или long double
на 10 не представляется в формате double
или long double
- поскольку для представления 10 требуется три значащих бита (101 ) 2 • 2 1 ), для точного произведения могут потребоваться более значимые биты, чем в double
. Как следствие, точный математический результат округляется, чтобы соответствовать формату с плавающей запятой. Другими словами, n *= 10;
меняет значение; он не просто умножает его на 10. Поэтому он не всегда будет давать цифры исходного числа.