2012-02-21 5 views
2

Составителям разрешено делать несколько допущений, которые могут привести к неопределенному поведению (например, если добавление не переполняется). Могут ли они сделать такое предположение относительно с плавающей запятой NaN?Может ли оптимизатор предположить, что плавающая точка не NaN?

Например:

double a = some_calc(); 
double b = a; 
if(a == b) 
    do_something(); 

Может оптимизатор удалить условный оператор и предположим, что это всегда так? Или он связан с правилами платформы с плавающей запятой (IEEE) и вынужден выполнять проверку в случае, если значение NaN?

То есть, может ли оптимизатор компилятора основываться на предположении, что double не содержит NaN? Поскольку стандарт C++ не говорит много о том, как работает плавающая точка на платформе, я не понимаю, действительно ли это полностью определено.

+0

Если реализация документа сама по себе является поддержкой NaN, то она должна поддерживать NaN. Оптимизатор является частью реализации. Это достаточно информации? ;-) –

+0

То есть, может ли реализация определить NaN таким образом, чтобы разрешить вышеупомянутую оптимизацию. Стандарт имеет функцию 'isnan', поэтому не будет потери функциональности. –

+0

Я не думаю, что для стандарта C++ требуется «NaN! = NaN», где «NaN» - это спокойный NaN. Если я прав, то реализация C++ может определять свои собственные не-цифры, такие как 'NaN == NaN', а затем оптимизация будет действительна. Реализация не будет поддерживать * IEEE * NaNs. Если я ошибаюсь, и для C++ требуется, что «NaN! = NaN», то оптимизатор не может обрабатывать «operator == (double, double)», как он обрабатывает 'operator == (int, int)' , –

ответ

2

Или это связано с платформой правил с плавающей точкой (IEEE)

Не обязательно, если реализация использует IEEE 754 числа с плавающей запятой, std::numeric_limits<double>::is_iec559 устанавливается истина.

и вынужден сделать проверку в случае, если значение NaN?

Если реализация делает использовать IEEE 754, результат арифметических операций должны соответствовать правилам IEEE с плавающей точкой, но, насколько сравнение идет, он может быть оптимизирован. Если тело some_calc доступно для анализа компилятором в той же системе перевода (или при генерации кода времени) и, это может сделать вывод, что он никогда не возвращает NaN (т.е. возвращает константу), его можно оптимизировать, поскольку семантика кода не изменяется.

+0

Таким образом, решение будет зависеть от того, сможет ли компилятор окончательно узнать, может ли 'some_calc' вернуть NaN. Если он не может знать со 100% уверенностью, он должен будет выполнить сравнение (или сделать нан-чек, если это может быть быстрее). –

+0

@ edA-qamort-ora-y, да, это верно для всех оптимизаций. Если тело функции непрозрачно для компилятора, оно ничего не может принять (функция может возвращать любое значение, а также иметь побочные эффекты) –

+2

Однако некоторые компиляторы имеют флаги оптимизатора, поэтому пользователь может сказать им: «Я не знаю, заботиться о NaNs. " С таким флагом компилятор тогда игнорирует возможность NaN здесь. –