The IEEE754 standard defines two classes of NaN, the quiet NaN, QNaN, and the signaling NaN, SNaN. When an SNaN is loaded into a floating point register, an exception is raised by the floating point unit.

QNaN is available to Delphi code through the constant named NaN that is declared in Math. The definition of that constant is:

const
  NaN = 0.0 / 0.0;

I would like to be able to use something similar to declare a constant that is a signaling NaN, but have not yet found a way to do that.

Naively you might write this code:

function SNaN: Double;
begin
  PInt64(@Result)^ := $7FF7FFFFFFFFFFFF;//this bit pattern specifies an SNaN
end;

But the ABI for floating point return values means that the SNaN is loaded into a floating point register so that it can be returned. Naturally that leads to an exception which rather defeats the purpose.

So you are then led to writing code like this:

procedure SetToSNaN(out D: Double);
begin
  PInt64(@D)^ := $7FF7FFFFFFFFFFFF;
end;

Now, this works, but it's very inconvenient. Suppose you need to pass an SNaN to another function. Ideally you would like to write:

Foo(SNaN)

but instead you have to do this:

var
  SNaN: Double;
....
SetToSNaN(SNaN);
Foo(SNaN);

So, after the build-up, here's the question.

Is there any way to write x := SNaN and have the floating point variable x assigned a value that is a signaling NaN?

Edit
Report