С/C++ трюки, чтобы реализовать плавающий порядок операций

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

Несколько операций с плавающей точкой в C сочетательный?

https://devblogs.microsoft.com/cppblog/do-you-prefer-fast-or-precise/

На C/C++ и математики порядок работы

Ссылки выше обсуждают глобальные варианты, но я хотел бы понять, если существуют местные директивы компилятора. Например, при выполнении синтеза аппаратных средств, можно заставить компилятор синтезировать логическое выражение дословно, не делая какого-либо сокращения.

Например, рассмотрим

#include <iostream>
#include <string>
#include <iomanip>

using std::cout;

int main()
{
    double a = 1.0 + 1.3e-16;
    double b = 1.0;
    double c = 100.0;

    double d = (a - b) / c;
    double e = a / c - b / c;

    cout << std::scientific;
    cout << "Calculation d = " << d << "\n";
    cout << "Calculation e = " << e << "\n";

    double f = 1.0;
    double g = 2e-15;
    double h = 1.0;
    double i = 1e-15;

    double j = (f + g) - (h + i);
    double k = (f - h) + (g - i);
    double m = f + g - h - i;
    double n = f - h + g - i;

    cout << "Calculation j = " << j << "\n";
    cout << "Calculation k = " << k << "\n";
    cout << "Calculation m = " << m << "\n";
    cout << "Calculation n = " << n << "\n";
}

Используя http://cpp.shя вам

Calculation d = 2.220446e-18
Calculation e = 1.734723e-18
Calculation j = 8.881784e-16
Calculation k = 1.000000e-15
Calculation m = 9.984014e-16
Calculation n = 1.000000e-15

Это зависит от оптимизации уровня я использовал, поэтому кажется, что компилятор будет вычислять все в порядке, я ожидаю, что на основе выражения, плюс еще ведет влево-вправо на +/- но это абсолютно гарантировано, когда оптимизация включена?

Я могу придумать сценарий, например, когда один из операндов уже сидя в каком-нибудь полезным реестр в результате это позволит сэкономить память двигаться, чтобы вычислить вещи в другом порядке, чем я написал, но будет поддерживать символические правильности.

В принципе я не могу начать пробовать различные хаки, чтобы исправить проблему, например, я читал, что объявив субпродуктов как volatile переменные поможет, поскольку мой пример не показать проблему. Поэтому я хотел бы знать, если это действительно не проблема, а если нет, то какие хитрости существуют.

+2
2019-09-19 00:14:55
источник
0 ответов

Посмотрите другие вопросы по меткам