Стандарт IEEE754 определяет два класса NaN, тихое NaN, QNaN и сигнализацию NaN, SNaN. Когда SNaN загружается в регистр с плавающей запятой, исключение генерируется блоком с плавающей точкой.
QNaN доступен для кода Delphi через константу с именем NaN
, которая объявлена в Math
. Определение этой константы:
const
NaN = 0.0 / 0.0;
Я хотел бы иметь возможность использовать что-то похожее, чтобы объявить константу, которая является сигнальной NaN, но еще не нашла способ сделать это.
Наивно вы можете написать этот код:
function SNaN: Double;
begin
PInt64(@Result)^ := $7FF7FFFFFFFFFFFF;//this bit pattern specifies an SNaN
end;
Но ABI для значений возвращаемых значений с плавающей запятой означает, что SNaN загружается в регистр с плавающей запятой, чтобы он мог быть возвращен. Естественно, это приводит к исключению, которое скорее поражает цель.
Итак, вы затем приводите к написанию кода следующим образом:
procedure SetToSNaN(out D: Double);
begin
PInt64(@D)^ := $7FF7FFFFFFFFFFFF;
end;
Теперь это работает, но это очень неудобно. Предположим, вам нужно передать SNaN в другую функцию. В идеале вы хотели бы написать:
Foo(SNaN)
но вместо этого вы должны сделать это:
var
SNaN: Double;
....
SetToSNaN(SNaN);
Foo(SNaN);
Итак, после наращивания, вот вопрос.
Есть ли способ написать x := SNaN
и иметь переменную с плавающей запятой x
присвоенное значение, которое является сигналом NaN?