syphilis has asked for the wisdom of the Perl Monks concerning the following question:
Hi,
This demo script requires a compiler (eg gcc) that provides the _Decimal64 type:
However, if I copy'n'past that C code across to a separate file and run it as a C program (using the very same compiler) I get correct output:
Yet, this now correctly outputs:
I've gazed upon the C code that Inline::C generates, and I've run the script through the C pre-processor, but I haven't managed to spot anything that helps me understand how this anomaly exists.
I've also spent some time trying various things that I hoped might trick Inline::C into behaving properly and I did find that this works:
There's nothing of much immediate importance with this ... but I can't stop scratching at it ;-)
Your insights are most welcome
Cheers,
Rob
This demo script requires a compiler (eg gcc) that provides the _Decimal64 type:
That outputs:use strict; use warnings; use Inline C => Config => BUILD_NOISY => 1, USING => 'ParseRegExp', #CLEAN_AFTER_BUILD => 0, ; use Inline C => <<'EOC'; #include <stdio.h> int foo(void) { _Decimal64 d64 = 0.DD; d64 *= -1.DD; if(d64 != 0.DD) printf("!= 0\n"); else printf("== 0\n"); if(d64 != -0.DD) printf("!= -0\n"); else printf("== -0\n"); return 0; } EOC foo();
which tells me that -0 != 0 (and that is contrary to IEEE standards).!= 0 == -0
However, if I copy'n'past that C code across to a separate file and run it as a C program (using the very same compiler) I get correct output:
AFAICS, all that has changed is that "foo" has been renamed to "main".#include <stdio.h> int main(void) { _Decimal64 d64 = 0.DD; d64 *= -1.DD; if(d64 != 0.DD) printf("!= 0\n"); else printf("== 0\n"); if(d64 != -0.DD) printf("!= -0\n"); else printf("== -0\n"); return 0; }
Yet, this now correctly outputs:
I'm seeing this behaviour on both Windows and Linux for a variety of perl versions and a variety of gcc compilers from 4.7.0 to 7.1.0 - so I'm hopeful that anyone else who has a gcc-4.x.x compiler (or later) will have no trouble reproducing the behaviour. Only other thing needed is Inline::C.== 0 == -0
I've gazed upon the C code that Inline::C generates, and I've run the script through the C pre-processor, but I haven't managed to spot anything that helps me understand how this anomaly exists.
I've also spent some time trying various things that I hoped might trick Inline::C into behaving properly and I did find that this works:
All I've done there is to move the test that foo() was previously doing, into a separate sub. That produces correct output of:use strict; use warnings; use Inline C => Config => BUILD_NOISY => 1, USING => 'ParseRegExp', #CLEAN_AFTER_BUILD => 0, ; use Inline C => <<'EOC'; #include <stdio.h> void _is_zero(_Decimal64 d64) { if(d64 != 0.DD) printf("!= 0\n"); else printf("== 0\n"); if(d64 != -0.DD) printf("!= -0\n"); else printf("== -0\n"); } int foo(void) { _Decimal64 d64 = 0.DD; d64 *= -1.DD; _is_zero(d64); return 0; } EOC foo();
Unfortunately the same approach doesn't work for the _Decimal128 type, where the same issue also arises.== 0 == -0
There's nothing of much immediate importance with this ... but I can't stop scratching at it ;-)
Your insights are most welcome
Cheers,
Rob
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Inline::C producing an absurd result
by BrowserUk (Patriarch) on May 08, 2017 at 10:55 UTC | |
by pryrt (Abbot) on May 08, 2017 at 13:49 UTC | |
by syphilis (Archbishop) on May 09, 2017 at 02:46 UTC | |
by syphilis (Archbishop) on May 08, 2017 at 13:19 UTC | |
Re: Inline::C producing an absurd result
by Anonymous Monk on May 08, 2017 at 20:02 UTC | |
by syphilis (Archbishop) on May 09, 2017 at 01:09 UTC |
Back to
Seekers of Perl Wisdom