Почему я получаю специфичный для платформы результат для std :: exp? [Дубликат]

На этот вопрос уже есть ответ:

Математика с плавающей точкой нарушена? 28 ответов Математические требования к точности стандартов C и C ++ 1 ответ

У меня есть программа, которая дает разные результаты под Android и Windows. Поскольку я проверяю выходные данные по двоичному файлу, содержащему ожидаемый результат, разница, даже если она очень мала (проблема округления), раздражает, и я должен найти способ ее исправить.

Вот пример программы:

#include <iostream>
#include <iomanip>
#include <bitset>

int main( int argc, char* argv[] )
{
    // this value was identified as producing different result when used as parameter to std::exp function
    unsigned char val[] = {158, 141, 250, 206, 70, 125, 31, 192};

    double var = *((double*)val);

    std::cout << std::setprecision(30);

    std::cout << "var is " << var << std::endl;
    double exp_var = std::exp(var);
    std::cout << "std::exp(var) is " << exp_var << std::endl;
}

Под Windows, скомпилированной с Visual 2015, я получаю вывод:

var is -7.87234042553191493141184764681
std::exp(var) is 0.00038114128472300899284561093161

Под Android / armv7, скомпилированный с g ++ NDK r11b, я получаю вывод:

var is -7.87234042553191493141184764681
std::exp(var) is 0.000381141284723008938635502307335

Так что результаты начинаются с e-20:

PC:      0.00038114128472300899284561093161
Android: 0.000381141284723008938635502307335

Обратите внимание, что моя программа выполняет много математических операций, и я заметил толькоstd::exp выдача разных результатов для одного и того же ввода ... и только для некоторых конкретных значений ввода (не проверялось, имеют ли эти значения одинаковое свойство), для большинства из них результаты идентичны.

Является ли это поведение "ожидаемым", разве нет гарантии, что в некоторых ситуациях будет тот же результат? Есть ли какой-нибудь флаг компилятора, который мог бы это исправить? Или мне нужно округлить результат, чтобы он закончился одинаково на обеих платформах? Тогда что будет хорошей стратегией для округления? Потому что округление аббревиатуры на e-20 потеряло бы слишком много информации, если вводvar очень маленький?

Редакция: я считаю, что мой вопрос не является дубликатом Математика с плавающей точкой нарушена?. Я получаю одинаковый результат на обеих платформах, толькоstd::exp для некоторых конкретных значений дает разные результаты.

Ответы на вопрос(1)

Ваш ответ на вопрос