bug-guile
[Top][All Lists]
Advanced

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

bug#13031: large numbers


From: Mark H Weaver
Subject: bug#13031: large numbers
Date: Mon, 03 Dec 2012 19:13:48 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux)

Hi Jozef,

I guess that on your system, (* 65536 65536) evaluates to 0.
Is that right?

If so, I believe the problem is caused by an aggressive optimization in
recent versions of Clang, which breaks Guile's logic for detecting
overflow when multiplying two fixnums.

Currently, Guile computes kk = xx * yy and checks for overflow by
verifying that kk / xx == yy.

I believe that Clang is optimizing out the check, because recent C
standards permit C implementations to assume that signed integer
arithmetic will never overflow.  For details, see:
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

One solution is to compile with the "-fwrapv" option, which should
disable the optimization.

Another solution is to apply the following patch.

Jozef, would you be willing to test this patch and tell me if it fixes
the problem?

   Many thanks,
      Mark


diff --git a/libguile/numbers.c b/libguile/numbers.c
index 52e227f..66c95db 100644
--- a/libguile/numbers.c
+++ b/libguile/numbers.c
@@ -7640,10 +7640,16 @@ scm_product (SCM x, SCM y)
       if (SCM_LIKELY (SCM_I_INUMP (y)))
        {
          scm_t_inum yy = SCM_I_INUM (y);
-         scm_t_inum kk = xx * yy;
-         SCM k = SCM_I_MAKINUM (kk);
-         if ((kk == SCM_I_INUM (k)) && (kk / xx == yy))
-           return k;
+#if SCM_I_FIXNUM_BIT < 32 && SCM_HAVE_T_INT64
+          scm_t_int64 kk = xx * (scm_t_int64) yy;
+          if (SCM_FIXABLE (kk))
+            return SCM_I_MAKINUM (kk);
+#else
+          scm_t_inum axx = (xx > 0) ? xx : -xx;
+          scm_t_inum ayy = (yy > 0) ? yy : -yy;
+          if (SCM_MOST_POSITIVE_FIXNUM / axx >= ayy)
+            return SCM_I_MAKINUM (xx * yy);
+#endif
          else
            {
              SCM result = scm_i_inum2big (xx);

reply via email to

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