* inum/double = on 64-bits
@ 2005-01-06 0:29 Kevin Ryde
2005-01-06 15:06 ` Greg Troxel
0 siblings, 1 reply; 3+ messages in thread
From: Kevin Ryde @ 2005-01-06 0:29 UTC (permalink / raw)
On a debian alpha, a comparison like
(= #x111111111111111 (exact->inexact #x111111111111110))
gives #t, where on a 32-bit system it's #f. The problem is rounding
in the scm_num_eq_p, an inum doesn't fit the mantissa of a double.
You can see exact->inexact isn't corrupting the value with say
(number->string (inexact->exact (exact->inexact #x111111111111110)) 16)
I'm looking at a fix like the following, which will add xx==(long)yy
on a system with a big inum.
/* On a 32-bit system an inum fits a double, we can cast the inum to a
double and compare.
But on a 64-bit system an inum is bigger than a double and casting
it to a double (call it dxx) will round. dxx is at worst 1 bigger
or smaller than xx, so if dxx==yy we know yy is an integer and fits
a long. So we cast yy to a long and compare with plain xx.
An alternative (for any size system actually) would be to check yy
is an integer (with floor) and is in range of an inum (compare
against appropriate powers of 2) then test xx==(long)yy. It's just
a matter of which casts/comparisons might be fastest or easiest for
the cpu. */
double yy = SCM_REAL_VALUE (y);
return SCM_BOOL ((double) xx == yy
&& (DBL_MANT_DIG >= SCM_I_FIXNUM_BIT-1
|| xx == (long) yy));
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: inum/double = on 64-bits
2005-01-06 0:29 inum/double = on 64-bits Kevin Ryde
@ 2005-01-06 15:06 ` Greg Troxel
2005-01-06 23:15 ` Kevin Ryde
0 siblings, 1 reply; 3+ messages in thread
From: Greg Troxel @ 2005-01-06 15:06 UTC (permalink / raw)
On a debian alpha, a comparison like
(= #x111111111111111 (exact->inexact #x111111111111110))
gives #t, where on a 32-bit system it's #f.
Is the language clear on what the right answer is? Are you saying
that the behavior is suboptimal, or a violation of R5RS?
On my system, I get #t. A perhaps related suboptimality is in
printing large inexact values.
On NetBSD/i386 2.0ish, guile 1.6.5:
guile> (= #x111111111111111 (exact->inexact #x111111111111110))
#t
guile> #x111111111111110
76861433640456464
guile> (exact->inexact #x111111111111110)
76861433640456500.0
guile> (inexact->exact (exact->inexact #x111111111111110))
76861433640456464
NetBSD/sparc64 (LP64) 2.0ish, guile 1.6.4:
guile> (= #x111111111111111 (exact->inexact #x111111111111110))
#t
guile> #x111111111111110
76861433640456464
guile> (exact->inexact #x111111111111110)
76861433640456500.0
guile> (inexact->exact (exact->inexact #x111111111111110))
76861433640456464
It seems odd to me (from a user viewpoint, but also from thinking
about the implementation) that inexact->exact can restore information
that had appeared missing.
I wonder if I am seeing the effects of the extra floating point bits
beyond IEEE754 on i386, but I see the same behavior on sparc64.
--
Greg Troxel <gdt@ir.bbn.com>
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: inum/double = on 64-bits
2005-01-06 15:06 ` Greg Troxel
@ 2005-01-06 23:15 ` Kevin Ryde
0 siblings, 0 replies; 3+ messages in thread
From: Kevin Ryde @ 2005-01-06 23:15 UTC (permalink / raw)
Cc: guile-devel
Greg Troxel <gdt@ir.bbn.com> writes:
>
> Is the language clear on what the right answer is?
r5rs cautions against relying on = for inexacts due to inaccuracies,
but I read that as inaccuracies from a calculation.
I'm looking at an inexact which is an integer, compared to an exact
which is an integer of a different value, and getting #t.
Such a comparison would give #f if you converted the inexact to an
exact first, I think it should be #f when you do it both ways.
In 1.8 comparisons (= bignum flonum) use the precise value of both, I
want to extend that to 64-bit inums for uniformity. I think the same
would be good for 1.6, though that would need the bignum+flonum case
attacked too.
> On my system, I get #t. A perhaps related suboptimality is in
> printing large inexact values.
The printing of inexacts is fairly dodgy, I believe. Convert to an
exact to print.
> On NetBSD/i386 2.0ish, guile 1.6.5:
>
> guile> (= #x111111111111111 (exact->inexact #x111111111111110))
> #t
I say it should be #f, which is what you get in 1.8. But on i386 this
is the bignum+flonum case, I'm only looking at the inum+flonum at this
moment.
> NetBSD/sparc64 (LP64) 2.0ish, guile 1.6.4:
>
> guile> (= #x111111111111111 (exact->inexact #x111111111111110))
> #t
Yep, this is the one I say should be #f. Those two values are not the
same.
> I wonder if I am seeing the effects of the extra floating point bits
> beyond IEEE754 on i386, but I see the same behavior on sparc64.
Those extra bits will affect intermediates in the C code, but the
actual SCM flonum is a double.
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2005-01-06 23:15 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-06 0:29 inum/double = on 64-bits Kevin Ryde
2005-01-06 15:06 ` Greg Troxel
2005-01-06 23:15 ` Kevin Ryde
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).