Двоичные числа с плавающей запятой не имеют десятичных цифр, как вы думаете.
Даже целые числа не сохраняются в виде десятичных цифр. Они представлены в двоичном виде. Когда вы используете % 10
и / 10
, вы рассчитываете десятичное представление для них. (Если бы они были сохранены с десятичным представлением, C, вероятно, имел бы некоторый оператор для доступа цифр, своего рода оператор индекса, такой как x[3]
, для получения третьей цифры x
. Вместо этого вы используете вычисления , например % 10
, для вычисления цифр.)
Во многих реализациях C используется базовый 64-битный двоичный формат IEEE-754 для double
. Предположим, что ваша реализация C делает, и вы выполняете x = 12.6;
. Тогда значение x
не равно 12.6, потому что 12.6 не может быть представлено в этом формате. Вместо этого 12.6 округляется до представимого значения. Если оно правильно округлено до ближайшего представимого значения, результат будет 12,5999999999999996447286321199499070644378662109375. Если вы правильно вычислите первую цифру после десятичной точки, вы получите 5, а не 6.
Можно написать код для получения этих цифр. В хорошей реализации на C проще всего использовать snprintf
для форматирования числа. Можно также написать вычисления для вычисления этих цифр, и C имеет функции fmod
, remainder
, remquo
и modf
, которые служат целям, аналогичным оператору %
для целых чисел. Однако умножение на 10 в двоичном формате с плавающей запятой проблематично, потому что умножение, как и большинство операций с плавающей запятой, дает результат, который является математическим результатом действительного числа, округленным до ближайшего представимого значения. Простое умножение на 10 попытается вычислить цифры, что приведет к ошибкам и даст неправильные результаты.
Правильный подход зависит от того, почему вы пытаетесь вычислить десятичное представление для числа с плавающей запятой, и какие параметры у вас есть относительнограницы чисел, желаемое количество цифр, насколько точным должно быть десятичное представление и т. д.