Если вы не установили режим округления, это должен быть режим по умолчанию IEEE-754, который округляется до ближайшего.
Для преобразования из целого числа в число с плавающей точкой стандарт C говорит (§6.3.1.4):
Когда значение целочисленного типа
конвертируется в реальный плавающий тип, если
конвертируемое значение может быть
представлены именно в новом типе,
это без изменений. Если значение
конвертируется в диапазоне значений
это может быть представлено, но не может быть
представлены точно, результат
либо ближайший выше или ближайший
нижнее представимое значение, выбранное в
определяемый реализацией способ. Если
конвертируемое значение находится за пределами
диапазон значений, которые могут быть
представлен, поведение
не определено.
Таким образом, оба поведения соответствуют стандарту C.
Стандарт C гласит (§F.5), что преобразования между форматами с плавающей точкой IEC60559 и последовательностями символов должны быть правильно округлены согласно стандарту IEEE-754. Для форматов не-IEC60559 это рекомендуется, но не обязательно. Стандарт IEEE-754 1985 года гласит (пункт 5.4):
Преобразования должны быть правильно округлены
как указано в разделе 4 для операндов
лежащий в пределах, указанных в
Таблица 3. В противном случае для округления до
ближайшее, ошибка в преобразованном
результат не должен превышать более чем
0,47 единиц в наименее значимой цифре адресата ошибка, которая
понесенные в результате округления
спецификации раздела 4, при условии
что показатель степени over / underflow не
происходят. В режимах направленного округления
ошибка должна иметь правильный знак
и не должен превышать 1,47 единиц в
последнее место.
Что в разделе (4) фактически говорится о том, что операция должна выполняться в соответствии с преобладающим режимом округления. То есть если вы измените режим округления, IEEE-754 говорит, что результат преобразования float-> string должен измениться соответственно. То же самое для целочисленных преобразований с плавающей запятой.
Пересмотренный в 2008 году стандарт IEEE-754 гласит (пункт 4.3):
Атрибут направления округления
влияет на все вычислительные операции
это может быть неточным. Неточное число
результаты с плавающей точкой всегда имеют
тот же знак, что и необоснованный результат.
Оба преобразования определены как вычислительные операции в разделе 5, поэтому они снова должны выполняться в соответствии с преобладающим режимом округления.
Я бы сказал, что Snow Leopard ведет себя корректно (при условии, что округляет результаты в соответствии с преобладающим режимом округления) Если вы хотите использовать старое поведение, вы всегда можете заключить вызовы printf
в код, который меняет режим округления, я полагаю, хотя это явно не идеально.
Кроме того, вы можете использовать спецификатор формата %a
(шестнадцатеричное число с плавающей запятой) на платформах, совместимых с C99. Поскольку результат этого преобразования всегда точен, он никогда не будет зависеть от преобладающего режима округления. Я не думаю, что библиотека Windows C поддерживает %a
, но, возможно, вы могли бы достаточно легко перенести реализацию BSD или glibc, если вам это нужно.