Во время короткого взгляда на исходный код system.math я обнаружил, что 64-разрядная версия Delphi Tokyo 10.2.3 сбрасывает денормальные IEEE-Doubles в ноль, как видно из следующей программы;
{$apptype console}
uses
system.sysutils, system.math;
var
x: double;
const
twopm1030 : UInt64 = $0000100000000000; {2^(-1030)}
begin
x := PDouble(@twopm1030)^;
writeln(x);
x := ldexp(1,-515);
writeln(x*x);
x := ldexp(1,-1030);
writeln(x);
end.
Для бита 32- выход так же, как ожидалось
8.69169475979376E-0311
8.69169475979376E-0311
8.69169475979376E-0311
но с 64-битным я получаю
8.69169475979375E-0311
0.00000000000000E+0000
0.00000000000000E+0000
Таким образом, в основном Токио может обрабатывать денормальные числа в 64-битном режиме, константа написана правильно, но из арифметических операций или даже с ldexp денормальный результат сбрасывается до нуля.
Можно ли подтвердить это наблюдение на других системах? Если да, где это документировано? (Единственная информация, которую я мог найти о нулевом промывании, заключается в том, что Denormals become zero when stored in a Real48
).
Обновление: Я знаю, что для обоих 32- и 64-бит используется единственная перегрузка. Для бита 32- используется FPU x87, и код ASM практически идентичен для всех прецизионностей (один, двойной, расширенный). FPU всегда возвращает 80-битный расширенный, который хранится в двойном без преждевременного усечения. 64-разрядный код выполняет настройку точности перед сохранением. Между тем я подал отчет о проблеме (https://quality.embarcadero.com/browse/RSP-20925), сосредоточив внимание на несогласованных результатах для 32- или 64-битных.