Re: [Chicken-hackers] [PATCH] Distinguish between positive and negative zero in flonums

2019-07-29 Thread John Cowan
On Mon, Jul 29, 2019 at 5:39 AM  wrote:


> (signum -0.0) => 0.0 seems totally right to me.
> >
>
> I wholeheartily disagree.
>

Here's my argument:  The signum function's definition guarantees that if
its argument is equal to zero, its result is equal to zero.  Since (= 0.0
-0.0) => #t, that guarantee is preserved.  However, in the case that you
want the sign of an underflowed value (which is the whole point of negative
zero), you can detect it if you want to.  For example, you can use (/ 1.0
result), which produces +inf.0 or -inf.0 respectively.


John Cowan  http://vrici.lojban.org/~cowanco...@ccil.org
You are a child of the universe no less than the trees and all other acyclic
graphs; you have a right to be here.  --DeXiderata by Sean McGrath
___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] [PATCH] Distinguish between positive and negative zero in flonums

2019-07-29 Thread Peter Bex
On Sun, Jul 28, 2019 at 05:06:27PM +1200, Evan Hanson wrote:
> One thing I noticed is that now (signum -0.0) => -0.0. Does that seem
> right? If so, it may be worth documenting that it's both exactness and
> sign-preserving.

It's probably correct.  SBCL does the same:

* (signum 0.0)
0.0
* (signum -0.0)
-0.0

Cheers,
Peter


signature.asc
Description: PGP signature
___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] [PATCH] Distinguish between positive and negative zero in flonums

2019-07-29 Thread felix . winkelmann
> That seems totally right to me.
> 

I wholeheartily disagree.

> On Sun, Jul 28, 2019 at 1:06 AM Evan Hanson  wrote:
> 
> > Thanks Peter, applied.
> >
> > On Sat, Jun 29, 2019 at 03:26:54PM +0200, Peter Bex wrote:
> > > I'm not happy with the hacky way the reader deals with these, but I could
> > > not really come up with a clean solution for it.  Suggestions for
> > > improvement are welcome.
> >
> > I experimented a bit with splitting the "go negative" logic from the "go
> > inexact" logic to perhaps make things more clear and avoid passing a
> > boolean around, but it didn't really help.
> >
> > One thing I noticed is that now (signum -0.0) => -0.0. Does that seem
> > right? If so, it may be worth documenting that it's both exactness and
> > sign-preserving.


felix


___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] [PATCH] Distinguish between positive and negative zero in flonums

2019-07-28 Thread John Cowan
That seems totally right to me.

On Sun, Jul 28, 2019 at 1:06 AM Evan Hanson  wrote:

> Thanks Peter, applied.
>
> On Sat, Jun 29, 2019 at 03:26:54PM +0200, Peter Bex wrote:
> > I'm not happy with the hacky way the reader deals with these, but I could
> > not really come up with a clean solution for it.  Suggestions for
> > improvement are welcome.
>
> I experimented a bit with splitting the "go negative" logic from the "go
> inexact" logic to perhaps make things more clear and avoid passing a
> boolean around, but it didn't really help.
>
> One thing I noticed is that now (signum -0.0) => -0.0. Does that seem
> right? If so, it may be worth documenting that it's both exactness and
> sign-preserving.
>
> Evan
>
> ___
> Chicken-hackers mailing list
> Chicken-hackers@nongnu.org
> https://lists.nongnu.org/mailman/listinfo/chicken-hackers
>
___
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers


Re: [Chicken-hackers] [PATCH] Distinguish between positive and negative zero in flonums

2019-06-29 Thread Peter Bex
On Sat, Jun 29, 2019 at 03:26:54PM +0200, Peter Bex wrote:
> Hi all,
> 
> Attached is a patch for #1627.
> 
> I'm not happy with the hacky way the reader deals with these, but I could
> not really come up with a clean solution for it.  Suggestions for
> improvement are welcome.

There was a small bug in the previous patch; it would also carry the sign
of the exponent into the final result, which is definitely not correct.
Very obscure case, but the nice numbers test suite from S7 found it :)

I also found another case: if there was an exponent at all, it would not
propagate the sign (so -0e1 would be 0.0 instead of -0.0).  I had to move
the go-inexact! call from scan-exponent down into scan-ureal, where the
sign is known.  This is fine, as the other call to scan-exponent was
inside scan-decimal-tail, before which scan-ureal already calls
go-inexact! as well.

This new patch has additional test cases for this as well.

Cheers,
Peter
From c134553e2fd3c2374e0c988d63e85802aa7dccdd Mon Sep 17 00:00:00 2001
From: Peter Bex 
Date: Sat, 29 Jun 2019 15:19:17 +0200
Subject: [PATCH] Distinguish between IEEE fp positive and negative zero

To be able to read these numbers, we need a bit of a hacky workaround
because we read integers and then convert them to inexact when needed,
but of course proper integers don't distinguish between positive and
negative zero.

To write these numbers, we need to use signbit(f) instead of checking
whether the number is negative in a "normal" way, because -0.0 is not
smaller than 0.

To compare them, we have the bizarre rule that = will not distinguish,
while equal? and eqv? will.

Fixes #1627, thanks to John Cowan for pointing out this regression
from CHICKEN 4.x (CHICKEN 4 with the numbers egg has the same bug
though).
---
 NEWS  |  5 +
 chicken.h |  9 -
 library.scm   | 27 ++-
 runtime.c |  5 +++--
 tests/library-tests.scm   | 14 ++
 tests/numbers-string-conversion-tests.scm | 10 ++
 6 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/NEWS b/NEWS
index e15ec4e3..da5dc62f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,10 @@
 5.1.1
 
+- Runtime system
+  - IEEE floating point negative zero is now properly handled: it can
+be read, written and distinguished by eqv? and equal?, but not =
+(fixes #1627, thanks to John Cowan).
+
 - Compiler
   - Fixed a bug in lfa2 pass which caused "if" or "cond" nodes to be
 incorrectly unboxed if the "else" branch had a flonum result type
diff --git a/chicken.h b/chicken.h
index 88bf4ab3..34a052cf 100644
--- a/chicken.h
+++ b/chicken.h
@@ -2622,6 +2622,12 @@ inline static int C_memcasecmp(const char *x, const char *y, unsigned int len)
   return 0;
 }
 
+inline static C_word C_ub_i_flonum_eqvp(double x, double y)
+{
+  /* This can distinguish between -0.0 and +0.0 */
+  return x == y && signbit(x) == signbit(y);
+}
+
 inline static C_word basic_eqvp(C_word x, C_word y)
 {
   return (x == y ||
@@ -2630,7 +2636,8 @@ inline static C_word basic_eqvp(C_word x, C_word y)
C_block_header(x) == C_block_header(y) &&

((C_block_header(x) == C_FLONUM_TAG &&
- C_flonum_magnitude(x) == C_flonum_magnitude(y)) ||
+ C_ub_i_flonum_eqvp(C_flonum_magnitude(x),
+   C_flonum_magnitude(y))) ||
 
 (C_block_header(x) == C_BIGNUM_TAG &&
  C_block_header(y) == C_BIGNUM_TAG &&
diff --git a/library.scm b/library.scm
index 994efc4d..965fe1c5 100644
--- a/library.scm
+++ b/library.scm
@@ -2398,9 +2398,12 @@ EOF
 ;; Shorthand for readability.  TODO: Replace other C_subchar calls with this
 (define-inline (%subchar s i) (##core#inline "C_subchar" s i))
 (define (##sys#string->compnum radix str offset exactness)
-  (define (go-inexact!)
+  (define negative #f)
+  (define (go-inexact! neg?)
 ;; Go inexact unless exact was requested (with #e prefix)
-(unless (eq? exactness 'e) (set! exactness 'i)))
+(unless (eq? exactness 'e)
+  (set! exactness 'i)
+  (set! negative (or negative neg?
   (define (safe-exponent value e)
 (and e (cond
 ((not value) 0)
@@ -2465,7 +2468,7 @@ EOF
 			   str start (car end) radix neg?)))
 (when hashes; Eeewww. Feeling dirty yet?
   (set! seen-hashes? #t)
-  (go-inexact!))
+  (go-inexact! neg?))
 (cons num (cdr end))
  (scan-exponent
   (lambda (start)
@@ -2474,7 +2477,6 @@ EOF
((#\+) 'pos) ((#\-) 'neg) (else #f
(and-let* ((start (if sign (fx+ start 1) start))
   (end (scan-digits start)))
- (go-inexact!)
  (cons (##core#inline_allocate