Подтвердить что ты не робот

Сделать C плавающей запятой букв плавать (а не удваивать)

Хорошо известно, что в C литералы с плавающей запятой (например, 1.23) имеют тип double. Как следствие, любой расчет, который их включает, увеличивается до двух.

Я работаю над встроенной системой реального времени, которая имеет модуль с плавающей запятой, который поддерживает только одинарные значения точности (float). Все мои переменные float, и этой точности достаточно. Мне не нужно (и не могу позволить себе) double вообще. Но каждый раз что-то вроде

if (x < 2.5) ...

происходит бедствие: замедление может быть до двух порядков. Конечно, прямой ответ - написать

if (x < 2.5f) ...

но это так легко пропустить (и его трудно обнаружить до слишком позднего времени), особенно когда значение "конфигурации" #define 'd в отдельном файле менее дисциплинированным (или только новым) разработчиком.

Итак, есть ли способ заставить компилятор обрабатывать все (с плавающей запятой) литералы как float, как будто с суффиксом f? Даже если это противоречит спецификациям, мне все равно. Или любые другие решения? Кстати, компилятор gcc.

4b9b3361

Ответ 1

-fsingle-precision-constant может использоваться флаг. Это приводит к тому, что константы с плавающей запятой загружаются с одной точностью, даже если это неточно.

Примечание. Это также будет использовать константы одиночной точности в операциях с переменными с двойной точностью.

Ответ 2

Вместо этого используйте предупреждения: -Wdouble-promotion предупреждает о неявной поплавке для двойной рекламы, как в вашем примере. -Wfloat-conversion будет предупреждать о случаях, когда вы все равно можете назначать удвоения для плавания.

Это лучшее решение, чем просто принудительное двойное значение до ближайшего значения float. Ваш код с плавающей точкой по-прежнему совместим, и вы не получите никаких неприятных сюрпризов, если двойное значение имеет положительное значение, скажем, меньше FLT_DENORM_MIN (при условии IEEE-754) или больше, чем FLT_MAX.

Ответ 3

Вы можете использовать определенные константы в (float) везде, где они используются, оптимизатор должен выполнять свою работу. Это портативное решение.

#define LIMIT 2.5

if (x < (float)LIMIT) ...

Ответ 4

Можно также использовать -Wunsuffixed-float-constants, возможно, в сочетании с некоторыми другими параметрами в принятом ответе выше. Тем не менее, это, вероятно, не поймает нефиксированные константы в системных заголовках. Нужно было бы использовать -Wsystem-headers чтобы поймать их тоже. Может генерировать много предупреждений...