Чего вам не хватает, так это того, что вы переводите каждое из ваших чисел в 2 базовые преобразования, а в x2 и x4 - в расширяющееся преобразование типов.
Прежде всего, у вас есть десятичные литералы, которыеКомпилятор преобразует в двоичные дроби типа float
, которые имеют точность 23 двоичных разряда (что эквивалентно примерно 7,2 десятичных цифр) и не могут точно представлять большинство десятичных дробей, даже те, которые соответствуют их точности.Затем x2 и x4 присваиваются double
переменным, но поскольку все, что не умещается в 23 двоичные цифры, уже обрезано, они магическим образом не восстанавливают точность, которая присутствовала в литералах.
Тогда, вы конвертируете двоичные дроби обратно в десятичную форму через printf
и получаете ранее упомянутое значение ca.7.2 правильные десятичные цифры, и все после этого отражает ошибку округления представлений, созданную базовым преобразованием.
Это в основном то же самое, что если вы попытаетесь преобразовать 1/3 в десятичную дробь 0,333 и обратно в правильную дробь 333/1000 - эй, а почему не 1/3?
Прочитайте справочник с плавающей точкой для получения дополнительной информации.