На информационном ресурсе применяются рекомендательные технологии (информационные технологии предоставления информации на основе сбора, систематизации и анализа сведений, относящихся к предпочтениям пользователей сети "Интернет", находящихся на территории Российской Федерации)

Linux

99 подписчиков

gcc и работа с вещественными числами

Здесь я рассказал о странной причуде языка C, с которой столкнулся в своей практике. В данной теме попытаюсь описать ещё об один "косяк", который может привести к некорректному результату, когда надеешься на правильную работу кода.

Итак, имеем следующий код:

#include <stdio.h>
int main()
{
    float a = 1.005, b = 1000;
    int c = a*b;
    printf("%d\n", c);
    return 0;
}

Компилируя этот код gcc 4.1.1, получаю 1004. Возникает вопрос - откуда такой странный результат? Даже это

int c = (float)(a*b);

также не даёт правильного результата. Оказалось, что старый стандарт языка C C89 ничего не регламентировал о способах работы с вещественными числами. Да ещё когда появилось расширение SSE, компиляторы начали считать смешенным образом - как посчитается быстрее, что-то на FPU, что-то на SSE.

В новом стандарте языка C C99 появилась некоторая определенность. Компилятор должен выставить значение макроса FLT_EVAL_METHOD (заголовочный файл float.h) в 0, 1, 2 для способа, которым он считает. Итак, 0 - всё считать так, как написано; 1 - float на самом деле считать в double и затем конвертировать обратно во float; 2 - всё считать в long double, конвертируя во float или double в конце вычислений соответственно.

Теперь, чтобы заставить считать прогу так, как надо, нужно собирать её

gcc proga.c -msse

Только после этого у меня в консоль вывелось число 1005. Чтобы была поддержка макроса FLT_EVAL_METHOD, используем директиву -std=c99.

Выдержка из мана по gcc (по поводу ключей -mmmx -msse -m3dnow):

These switches enable or disable the use of built-in functions that allow direct access to the MMX, SSE and 3Dnow extensions of the instruction set.

О ключе -mfpmath:

To have SSE/SSE2 instructions generated automatically from floating-point code, see -mfpmath=sse.

-mfpmath может принимать ещё значения "387" и "sse,387".

Картина дня

наверх