Конференция "Начинающим" » Директива {$EXCESSPRECISION OFF}
 
  • dmk © (25.10.17 17:48) [0]
    Всем привет!
    Никто не сталкивался с проблемой при использовании директивы {$EXCESSPRECISION OFF}?
    Она вроде как должна отключать повышенную точность, т.е. если используется тип Single, то он вычисляется как Single. Просто что ON, что OFF Delphi генерит одинаковый код и генерит значения Double.
    На ассемблере это выглядит как конвертирование в Double: svtss2sd xmm0, xmm0
    Просто приходится такие участки вручную на асме переделывать. Компилятор не очень хорошо справляется со своими директивами. Хотя может я чего не знаю?
    Delphi XE6 Prof / Win10 x64
  • dmk © (25.10.17 17:55) [1]
    Пытаюсь вычислить машинный эпсилон для сравнения и точности.
    Код такой:


    function MSingleEpsilon: Single;
    var
     R: Single;

    begin
     R := 1.0;
     while (1.0 + R / 2.0) > 1.0 do R := (R / 2.0);
     Result := R;
     //Result := 0.000000000000000222044604925031;
    end;

    function MDoubleEpsilon: Double;
    var
     R: Double;

    begin
     R := 1.0;
     while (1.0 + R / 2.0) > 1.0 do R := (R / 2.0);
     Result := R;
     //Result := 0.000000000000000222044604925031;
    end;

    initialization
     {$EXCESSPRECISION OFF}
     SingleEpsilon := MSingleEpsilon;
     {$EXCESSPRECISION ON}
     DoubleEpsilon := MDoubleEpsilon;


    Он мне и там и там выдает одинаковый результат.
  • KilkennyCat © (25.10.17 18:05) [2]
    само-то приложение х64?
  • rrrrrrr © (25.10.17 18:06) [3]
    а с какой целью директива всунута в инициализацию?
  • dmk © (25.10.17 18:42) [4]
    >само-то приложение х64?
    Да.

    >а с какой целью директива всунута в инициализацию?
    Я ее в разных местах ставил. Внутри функции и в обертке тоже не работает. Это просто последний вариант.
  • dmk © (25.10.17 18:44) [5]
    initialization относится к сегменту кода после компиляции.
    Какая разница? Там можно «лепить» все что угодно.
  • dmk © (25.10.17 19:00) [6]
    Для Single дожен быть результат ~1.19e-07, а для Double  ~2.20e-16.
  • kilkennycat © (25.10.17 19:41) [7]

    > dmk ©   (25.10.17 18:42) [4]
    > >само-то приложение х64?
    > Да.

    тогда работает ))
    в справке сказано, что лишь промежуточные вычисления меняют точность.я не понял, что именно имеется ввиду...
  • rrrrrr © (25.10.17 19:43) [8]
    Какая разница? Там можно «лепить» все что угодно.

    Type
    Switch
    Syntax{$EXCESSPRECISION ON}, {$EXCESSPRECISION OFF}
    Default {$EXCESSPRECISION ON}
    Scope Local
  • rrrrrr © (25.10.17 19:48) [9]
    плюс

    Switch directives are either global or local:

    Global directives affect the entire compilation and must appear before the declaration part of the program or the unit being compiled.

    Local directives affect only the part of the compilation that extends from the directive until the next occurrence of the same directive.
    и таки да,
    They can appear anywhere.

    то есть лепить-то её можно куда угодно,
    но будет ли она действовать на тот кусок какой тебе хочется - вопрос уже иной
  • dmk © (25.10.17 20:07) [10]
    >но будет ли она действовать на тот кусок какой тебе хочется - вопрос уже иной
    Не пашет нигде. Все перепробовал. Хоть в теле процедуры, хоть вначале, хоть в конце.
    Компилятор относится к ней как к комментарию :(
  • rrrrrr © (25.10.17 20:12) [11]
    ну окей.
    допустим оно на самом деле работает.
    и допустим что разница есть.

    но она же все равно меньше точности дабла
    там что-то типа 15 значащих всего
  • dmk © (25.10.17 20:30) [12]
    Ну он нужен для коррекции ошибок. Если я сравниваю два single, то они обычно не равны из-за этого epsilon. Мне его надо отнять и округлить до нужных разрядов. Тогда они становятся равны. IsEqual так сделан.

    AMargin это чаще всего машинный эпсилон. Зависит от случая.

    function IsEqual(const ANumber1, ANumber2: Double; const AMargin: Double = cMargin): Boolean;
    begin
     Result := Abs(ANumber1-ANumber2) <= AMargin;
    end;


    Мне надо для вычисления погрешностей Z-buffer, так как он single. Single просто пишется быстрее чем Double. Потому и использую. Чтобы не было Z-Fighting'а.

    Тут немого об этом:
    http://www.gamedev.ru/code/forum/?id=230831&page=5
 
Конференция "Начинающим" » Директива {$EXCESSPRECISION OFF}
Есть новые Нет новых   [118410   +20][b:0][p:0.001]