]> www.ginac.de Git - cln.git/commitdiff
Avoid shifting a 32-bit zero value by more than 31 bits.
authorBruno Haible <bruno@clisp.org>
Mon, 29 Aug 2005 13:14:22 +0000 (13:14 +0000)
committerBruno Haible <bruno@clisp.org>
Mon, 29 Aug 2005 13:14:22 +0000 (13:14 +0000)
ChangeLog
src/integer/bitwise/cl_I_ash_I.cc

index 238ca860ab656836a151ed26e4b6d876f6b3fc57..bde1149c7b6f092b0d973de2142dd4ca69b49669 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2005-08-27  Bruno Haible  <bruno@clisp.org>
+
+       * src/integer/bitwise/cl_I_ash_I.cc (ash): Avoid shifting a 32-bit
+       zero value by more than 31 bits.
+
 2005-08-27  Bruno Haible  <bruno@clisp.org>
 
        Make the long-float overflow check work on 64-bit platforms.
index 2ea5cd2419b0a98d7c1b699428ccbb351b4011b9..f4f6b9cf576696a76d82a703b3c4d79dac6f8838 100644 (file)
@@ -52,6 +52,7 @@ const cl_I ash (const cl_I& x, const cl_I& y)
                            || len == ceiling(log2_intDsize+intCsize+1,intDsize))
                                if (mspref(arrayMSDptr(bn->data,len),0) >= (uintD)bit((log2_intDsize+intCsize)%intDsize))
                                        cl_ash_error(y);
+                       #if (log2_intDsize+intCsize > intDsize)
                        #define IF_LENGTH(i)  \
                          if (bn_minlength <= i && i <= ceiling(log2_intDsize+intCsize+1,intDsize) && (i == ceiling(log2_intDsize+intCsize+1,intDsize) || len == i))
                        IF_LENGTH(1)
@@ -68,6 +69,11 @@ const cl_I ash (const cl_I& x, const cl_I& y)
                                cl_abort();
                        #undef IF_LENGTH
                        k = k << (intDsize-log2_intDsize);
+                       #else
+                       // log2_intDsize+intCsize <= intDsize,
+                       // implies len==1 or len==2 && lspref(arrayLSDptr(bn->data,len),1) == 0.
+                       k = 0;
+                       #endif
                        k |= lspref(arrayLSDptr(bn->data,len),0) >> log2_intDsize;
                        i = lspref(arrayLSDptr(bn->data,len),0) % intDsize;
                        #endif
@@ -123,6 +129,7 @@ const cl_I ash (const cl_I& x, const cl_I& y)
                            || len == ceiling(log2_intDsize+intCsize+1,intDsize))
                                if (mspref(arrayMSDptr(bn->data,len),0) < (uintD)(-bit((log2_intDsize+intCsize)%intDsize)))
                                        goto sign;
+                       #if (log2_intDsize+intCsize > intDsize)
                        #define IF_LENGTH(i)  \
                          if (bn_minlength <= i && i <= ceiling(log2_intDsize+intCsize+1,intDsize) && (i == ceiling(log2_intDsize+intCsize+1,intDsize) || len == i))
                        IF_LENGTH(1)
@@ -139,6 +146,11 @@ const cl_I ash (const cl_I& x, const cl_I& y)
                                cl_abort();
                        #undef IF_LENGTH
                        k = k << (intDsize-log2_intDsize);
+                       #else
+                       // log2_intDsize+intCsize <= intDsize,
+                       // implies len==1 or len==2 && lspref(arrayLSDptr(bn->data,len),1) == ~0.
+                       k = 0;
+                       #endif
                        k |= (uintD)(~lspref(arrayLSDptr(bn->data,len),0)) >> log2_intDsize;
                        i = (uintD)(-lspref(arrayLSDptr(bn->data,len),0)) % intDsize;
                        if (i == 0)