2017-02-08 16 views
4

Почему эти два возвращаемых значения функции cbrt() различны?Strange cbrt() result on linux in C

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

int main() { 
    double nb = 56623104; 
    double v1 = cbrt(nb); 
    printf("v1 -> %.15f\n",v1); 

    double v2 = cbrt((double) 56623104); 
    printf("v2 -> %.15f\n",v2); 
} 

Компиляция:

НКУ toto.c -o тото -lm & & ./toto

Результат:

v1 -> 384.000000000000057
v2 -> 384.000000000000000

+2

Поместите библиотеки ('-lm') за исходными или объектными файлами (' toto.c') для надежности. Что произойдет, если вы опустите опцию -lm? Он не должен связываться, но ... Вы посмотрели на ассемблер? Компилятор оценивает один из вызовов функций и оставляет его во время выполнения? –

+0

Если вы используете любой уровень выбора (01, O2, O3 или Ofast), результат будет таким же. Я разобрал его, и я понимаю, почему он это делает. Теперь я пытаюсь объяснить, почему компилятор делает это. – Anty

+0

Получаете ли вы такое же поведение с '#undef cbrt'? –

ответ

3

Поздравляем, это ошибка компилятора. Компилятор оптимизирует ваш код, оценивая один из cbrt звонков загодя, к сожалению, версия компилятора cbrt отличается от вашей версии в libm. Вы также заметите, что прохождение -O2 приводит к тому, что результат v2 будет «неправильным» (даже если это правильно, математически).

Я проверил, что ошибка существует в моей системе

куб.см (Debian 6.3.0-5) 6.3.0 20170124

Эта ошибка следует сообщать разработчикам компиляторов (https://gcc.gnu.org/bugs/) , но лучше сначала искать репозиторий ошибок.

+0

Я подтверждаю то же поведение, в том числе эффект оптимизации, на CentOS 7.3 (cc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)). Кроме того, я обнаружил, что '-fexcess-precision = standard' не влияет на результаты. –