This
new P0, .PerlNum
set P0, 0.0
print P0
print "\n"
set P0, -0.0
print P0
print "\n"
end
prints this
0
0
rather than say this
0
-0
For reference,
perl -e 'print -0.0,"\n"'
prints
-0
Thanks to ruby's test suite for the catch.
Mitchell
I do consider -0.0 as a bug ;)
> This
> new P0, .PerlNum
> set P0, 0.0
Both setting P0 to - or + zero has the same effect:
$ parrot -t 0.pasm
0 new P0, 35 - P0=NULL,
3 set P0, 0 - P0=PerlNum=PMC(0x40305850 Num:0 Int:0),
6 print P0 - P0=PerlInt=PMC(0x40305850 Num:0 Int:0)
that is morphing the PerlNum to a PerlInt.
> Mitchell
leo
I do consider -0.0 as a bug ;)
;)
However, distinguishing 0.0 from -0.0 is floating point standard.
And thus needed for interoperating with standards-following systems.
Such as perl. (And ruby and python.)
Windows apparently has issues (witness assorted notes in perl source).
> This
> new P0, .PerlNum
> set P0, 0.0
Both setting P0 to - or + zero has the same effect:
$ parrot -t 0.pasm
0 new P0, 35 - P0=NULL,
3 set P0, 0 - P0=PerlNum=PMC(0x40305850 Num:0 Int:0),
6 print P0 - P0=PerlInt=PMC(0x40305850 Num:0 Int:0)
that is morphing the PerlNum to a PerlInt.
Ah. So -0.0 needs to be special cased.
There is no int -0, so the morph has to be avoided.
The relevant code seems to be perlnum.pmc's set_number_native() op:
void set_number_native (FLOATVAL value) {
INTVAL vali = (INTVAL) value;
PMC_num_val(SELF) = value;
if (value == vali)
DYNSELF.set_integer_native(vali);
}
set_integer_native() does the morph.
So obviously what is needed is to change
if (value == vali)
to
if (value == vali && (0 != vali || ...something...))
perl 5.9.0 devotes several configuration arguments to finding a
floating point classifier (fpclass or similar). And 100+ lines of
perl.h to using them. Defines quite a few macros including
Perl_fp_class_nzero(x). But I don't immediately see where they
are being used...? Perhaps there is an easier way?
I'm going to leave it there.
We are currently not doing the right thing.
Perl does, somehow, and thus might be looked at.
Something for the todo list.
Mitchell
> if (value == vali && (0 != vali || ...something...))
Yep here it is.
Do we *really* need that crap?
> Mitchell
leo
That depends on who "we" are, unfortunately.
Larry
> perl 5.9.0 devotes several configuration arguments to finding a
> floating point classifier (fpclass or similar). And 100+ lines of
> perl.h to using them. Defines quite a few macros including
> Perl_fp_class_nzero(x). But I don't immediately see where they
> are being used...? Perhaps there is an easier way?
I've looked now for this "something" above. Libc does provide a macro
C<signbit(x)> which does the right thing.
config/gen/platform/generic/math.h has now a new macro Parrot_is_nzero,
works for __GNUC__.
Other compilers/platforms needs still work.
> Something for the todo list.
I added in your test, so ...
> Mitchell
leo
As requested. I may have mis-threaded this--sorry if I did.
> All~
>
> I just discovered that my system does have copysign so the following
> does link correctly on it.
>
> # define Parrot_is_nzero(x) ((x) == copysign(0.0, -1.0))
>
> Thus this could be usable as a default if signbit is unavailable.
>
> Matt
--
Brent "Dax" Royal-Gordon <br...@brentdax.com>
Perl and Parrot hacker
Oceania has always been at war with Eastasia.
use that if signbit isn't, patch? applied ;)
Thanks,
leo