guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

inexact->exact on nan and inf


From: Kevin Ryde
Subject: inexact->exact on nan and inf
Date: Wed, 24 Sep 2003 09:50:54 +1000
User-agent: Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3 (gnu/linux)

        * numbers.c (scm_inexact_to_exact): Don't depend on what double->long
        cast gives for values bigger than a long, or for nan or inf.

        * tests/numbers.test (inexact->exact): New tests.

This is merely a defensive proposal, it actually comes out ok on my
i386 debian already, since casting double->long gives 0x80000000 or
0x7FFFFFFF for values out of range, which of course don't pass
SCM_FIXABLE.  But it doesn't seem wise to assume such values.

New code, for ease of contemplation,

      /* The values SCM_MOST_POSITIVE_FIXNUM+1 and SCM_MOST_NEGATIVE_FIXNUM
         are both powers of 2, so there's no rounding when making "double"
         values from them.  If plain SCM_MOST_POSITIVE_FIXNUM was used it
         could get rounded on a 64-bit machine, hence the "+1".

         The use of floor to force to an integer value ensures we don't
         depend on how a double->long cast will round or how mpz_set_d will
         round.  For reference, double->long probably follows the hardware
         rounding mode, whereas mpz_set_d truncates towards zero.  */

      double u = SCM_REAL_VALUE (z);
      if (xisinf (u) || xisnan (u))
        scm_num_overflow (s_scm_inexact_to_exact);
      u = floor (u + 0.5);
      if (u < (double) (SCM_MOST_POSITIVE_FIXNUM+1)
          && u >= (double) SCM_MOST_NEGATIVE_FIXNUM)
        return SCM_MAKINUM ((long) u);
      else
        return scm_i_dbl2big (u);


Attachment: numbers.c.inexact-nan.diff
Description: Text document

Attachment: numbers.test.inexact.diff
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]