Как интерпретируются литералы с плавающей точкой в ​​C? - PullRequest
2 голосов
/ 16 марта 2009

В программе на Си, когда вы пишете литерал с плавающей точкой, такой как 3.14159, существует ли стандартная интерпретация или это зависит от компилятора или архитектуры? Java чрезвычайно ясно о том, как интерпретируются строки с плавающей запятой, но когда я читаю K & R или другую документацию на C, проблема кажется незаметной.

Ответы [ 3 ]

5 голосов
/ 16 марта 2009

Это зависит от архитектуры. Это обычно означает IEEE 754, но не обязательно. Стандарт C (ISO 9899: 1999) обсуждает это главным образом в разделе 5.2.4.2.2 «Характеристики плавающих типов».

3 голосов
/ 16 марта 2009

Из стандарта C99, раздел 6.4.4.2. Плавающие константы, параграф 3 (выделено мной):

Значимая часть интерпретируется как (десятичное или шестнадцатеричное) рациональное число; последовательность цифр в показательной части интерпретируется как десятичное целое число. Для десятичной Плавающие константы, показатель степени показывает степень 10, на которую значимая часть быть масштабированным. Для шестнадцатеричных плавающих констант показатель степени показывает степень 2 с помощью которого значимая часть должна быть расширена. Для десятичных плавающих констант, а также для шестнадцатеричные плавающие константы, когда FLT_RADIX не является степенью 2, результат либо ближайшее представимое значение или большее или меньшее представимое значение немедленно рядом с ближайшим представимым значением, выбранным способом, определяемым реализацией . Для шестнадцатеричных плавающих констант, когда FLT_RADIX является степенью 2, результат правильно округлено.

Итак, вы получите константу в пределах одного ULP способом, определяемым реализацией. Напомним, что определяемый реализацией означает, что реализация (в данном случае среда выполнения C) может выбрать любой из параметров, но этот выбор должен быть задокументирован . Итак, вы можете обратиться к документации по времени выполнения libc, чтобы узнать, как происходит округление.

2 голосов
/ 16 марта 2009

Вам непонятно, имеете ли вы в виду литерал с плавающей запятой как часть исходного кода (для синтаксического анализа компилятором двоичного представления, зависящего от архитектуры) или сканируемый библиотечными функциями, например scanf(), atof(), strtol(), strtod() и strtold() (во время выполнения для преобразования в значение float, double или long double в памяти).

В первом случае это часть ISO / IEC 9899: 1999 (ISO C99), §6.4.4.2 «Плавающие константы». Он определяет и лексикон, и то, как его следует интерпретировать.

Во втором случае поведение библиотечных функций определено в §7.20.1 «Числовые функции преобразования».

У меня нет печатной копии предыдущего стандарта (ANSI C, 1989), но я уверен, что он также очень точно определяет, как числа с плавающей запятой анализируются и преобразуются.

В случае, если вы хотите узнать, существует ли стандарт для представления этих значений в двоичном формате в памяти, ответ - нет. Язык C предназначен для того, чтобы быть близким к архитектуре и не налагать на него ограничений. Таким образом, представление в памяти всегда зависит от архитектуры. Но стандарт C определяет, как арифметика должна выполняться над значениями с плавающей запятой. Это соответствует стандарту IEC 60559. В стандарте ISO C99 он описан в Приложении F (норматив), «Арифметика с плавающей точкой в ​​IEC 60559». Реализация может реализовывать или не реализовывать этот стандарт. Если это так, он должен определить имя препроцессора __STDC_IEC_559__.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...