On 2017/5/13 10:25, Vincent Lefevre wrote:
On 2017-05-12 23:46:09 +0800, Liu Hao wrote:
But if you do this, you're out of scope of the standards.
Moreover, I suppose that you will also get a floating-point exception
on a signaling NaN, in which case, on this example, this isn't
distinguishable from a signaling NaN.
A QNaN doesn't generate an exception regardless of the x87 control word.
To make a QNaN, replace the last three bytes of `data` with `0xc0, 0xff,
0x7f`. The last example would then exit normally with the output 'nan'.
I will show an example later.
But the goal of Intel's x87 80-bit format and the IEEE 754-1985 spec
was to regard this format as a conforming double-extended format.
And AFAIK, the intent of IEEE 754-2008 was not to break this.
I don't think ISO C forbids existence of `trap representation` of
`long double`.
Anyway, this is not a trap representation as shown above.
It does generate an exception so why do you think it is not a trap
representation?
FXAM is neither an IEEE 754 operation, nor an ISO C operation.
Let's try ==, which corresponds to the IEEE 754 equality operator:
#include <stdio.h>
int main (void)
{
long double ld = 0;
unsigned char data[10] = {
0x5b, 0x01, 0x04, 0x5e, 0x85, 0x00, 0x00, 0x00, 0xd8, 0x59
};
__builtin_memcpy(&ld, data, 10);
printf ("NaN? %s\n", ld == ld ? "no" : "yes");
return 0;
}
This gives:
NaN? yes
So, it is regarded as a NaN.
Let's try `=` which corresponds to the IEEE 754 equality operator too:
-------------------------------------------------------
lh_mouse@lhmouse-dev:~$ cat test.c
#include <stdio.h>
#include <math.h>
int main (void)
{
unsigned short fcw;
__asm__ volatile (
"fstcw %0; "
"andw $-2, %0; "
"fldcw %0; "
: "=m"(fcw)
);
long double ld = 0;
unsigned char data[10] = {
0x5b, 0x01, 0x04, 0x5e, 0x85, 0x00, 0x00, 0x00, 0xd8, 0x59
};
__builtin_memcpy(&ld, data, 10);
long double y = 1;
y = ld;
printf ("%Lg\n", y);
return 0;
}
lh_mouse@lhmouse-dev:~$ gcc test.c -Wall -Wextra -pedantic -std=c99
lh_mouse@lhmouse-dev:~$ ./a.out
5.11212e+1984
-------------------------------------------------------
Then replace it with a QNaN:
-------------------------------------------------------
lh_mouse@lhmouse-dev:~$ sed -i 's/0x00, 0xd8, 0x59/0xc0, 0xff, 0x7f/' test.c
lh_mouse@lhmouse-dev:~$ gcc test.c -Wall -Wextra -pedantic -std=c99
lh_mouse@lhmouse-dev:~$ ./a.out
nan
-------------------------------------------------------
Then replace it with a SNaN:
-------------------------------------------------------
lh_mouse@lhmouse-dev:~$ gcc test.c -Wall -Wextra -pedantic -std=c99
lh_mouse@lhmouse-dev:~$ ./a.out
nan
-------------------------------------------------------
So, it is not regarded as a NaN.
--
Best regards,
LH_Mouse