]> www.ginac.de Git - cln.git/blobdiff - src/integer/bitwise/cl_I_ash_I.cc
Avoid some "suggest explicit braces to avoid ambiguous ‘else’" warnings.
[cln.git] / src / integer / bitwise / cl_I_ash_I.cc
index 2ea5cd2419b0a98d7c1b699428ccbb351b4011b9..6c11f475197bb37d19b4b0a43f3d01672cd5560f 100644 (file)
@@ -1,7 +1,7 @@
 // ash().
 
 // General includes.
-#include "cl_sysdep.h"
+#include "base/cl_sysdep.h"
 
 // Specification.
 #include "cln/integer.h"
@@ -9,9 +9,8 @@
 
 // Implementation.
 
-#include "cl_I.h"
-#include "cl_DS.h"
-#include "cl_I_ash.h"
+#include "integer/cl_I.h"
+#include "base/digitseq/cl_DS.h"
 
 namespace cln {
 
@@ -21,11 +20,11 @@ const cl_I ash (const cl_I& x, const cl_I& y)
     // x = 0 -> 0 als Ergebnis
     // y = 0 -> x als Ergebnis
     // y > 0 -> y = intDsize*k + i, j=k+(1 falls i>0, 0 falls i=0).
-    //          j Wörter mehr reservieren, k Nullwörter, dann übertragen,
+    //          j Wörter mehr reservieren, k Nullwörter, dann übertragen,
     //          bei i>0: um i Bits links schieben (i=1 geht einfacher).
-    // y < 0 -> y <= - intDsize * (Länge(A0) in Digits) -> Ergebnis = 0 oder -1.
-    //          Sonst: -y = intDsize*k + i mit k<Länge(A0).
-    //                  Übertrage die (Länge(A0)-k) MSDigits,
+    // y < 0 -> y <= - intDsize * (Länge(A0) in Digits) -> Ergebnis = 0 oder -1.
+    //          Sonst: -y = intDsize*k + i mit k<Länge(A0).
+    //                  Übertrage die (Länge(A0)-k) MSDigits,
     //                  falls i>0: schiebe sie um i Bits nach rechts (i=1 geht einfacher).
        if (zerop(x))
                return 0;               // x=0 -> 0 als Ergebnis
@@ -35,23 +34,24 @@ const cl_I ash (const cl_I& x, const cl_I& y)
        if (!minusp(y)) {
                // y>=0
                var uintL i; // i = y mod intDsize, >=0, <intDsize
-               var uintL k; // k = y div intDsize, >=0, <2^intCsize
+               var uintC k; // k = y div intDsize, >=0, <2^intCsize
                if (bignump(y)) {
                        #if (log2_intDsize+intCsize <= cl_value_len-1)
                        // y >= 2^(cl_value_len-1) >= intDsize*2^intCsize
-                       cl_ash_error(y);
+                       throw ash_exception(y);
                        #else
                        // y >= 2^(cl_value_len-1)
                        // usable only if y < intDsize*2^intCsize
                        var cl_heap_bignum* bn = TheBignum(y);
                        var uintC len = bn->length;
                        if (len > ceiling(log2_intDsize+intCsize+1,intDsize))
-                               cl_ash_error(y);
+                               throw ash_exception(y);
                        // bn_minlength <= len <= ceiling(log2_intDsize+intCsize+1,intDsize).
                        if (bn_minlength == ceiling(log2_intDsize+intCsize+1,intDsize)
                            || len == ceiling(log2_intDsize+intCsize+1,intDsize))
                                if (mspref(arrayMSDptr(bn->data,len),0) >= (uintD)bit((log2_intDsize+intCsize)%intDsize))
-                                       cl_ash_error(y);
+                                       throw ash_exception(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)
@@ -65,23 +65,28 @@ const cl_I ash (const cl_I& x, const cl_I& y)
                        else IF_LENGTH(5)
                                k = get_uint4D_Dptr(arrayLSDptr(bn->data,5) lspop 1);
                        else
-                               cl_abort();
+                               throw runtime_exception();
                        #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
                } else {
-                       var uintL y_ = FN_to_L(y); // Wert von y, >=0, <intDsize*2^intCsize
+                       var uintV y_ = FN_to_V(y); // Wert von y, >=0, <intDsize*2^intCsize
                        i = y_%intDsize;
                        k = floor(y_,intDsize);
                }
                var uintD* LSDptr;
                var uintC len;
                var const uintD* x_LSDptr;
-               I_to_NDS_nocopy(x, ,len=,x_LSDptr=,cl_false,); // DS zu x bilden.
-               if (k >= (uintC)(~(uintC)len)) // kann len+k+1 Überlauf geben?
-                       { cl_ash_error(y); } // ja -> Fehler
+               I_to_NDS_nocopy(x, ,len=,x_LSDptr=,false,); // DS zu x bilden.
+               if (k >= (uintC)(~len)) // kann len+k+1 Überlauf geben?
+                       { throw ash_exception(y); } // ja -> Fehler
                num_stack_alloc_1(len+k,,LSDptr=);
                LSDptr = clear_loop_lsp(LSDptr,k); // k Nulldigits
                var uintD* MSDptr = copy_loop_lsp(x_LSDptr,LSDptr,len);
@@ -105,7 +110,7 @@ const cl_I ash (const cl_I& x, const cl_I& y)
        } else {
                // y<0
                var uintL i; // i = (-y) mod intDsize, >=0, <intDsize
-               var uintL k; // k = (-y) div intDsize, >=0, <2^intCsize
+               var uintC k; // k = (-y) div intDsize, >=0, <2^intCsize
                if (bignump(y)) {
                        #if (log2_intDsize+intCsize <= cl_value_len-1)
                        // -y-1 >= 2^(cl_value_len-1) >= intDsize*2^intCsize
@@ -123,6 +128,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)
@@ -136,9 +142,14 @@ const cl_I ash (const cl_I& x, const cl_I& y)
                        else IF_LENGTH(5)
                                k = ~get_sint4D_Dptr(arrayLSDptr(bn->data,5) lspop 1);
                        else
-                               cl_abort();
+                               throw runtime_exception();
                        #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)
@@ -146,7 +157,7 @@ const cl_I ash (const cl_I& x, const cl_I& y)
                                        goto sign;
                        #endif
                } else {
-                       var uintL y_ = -FN_to_L(y); // Wert von -y, >0, <intDsize*2^intCsize
+                       var uintV y_ = -FN_to_V(y); // Wert von -y, >0, <intDsize*2^intCsize
                        i = y_%intDsize;
                        k = floor(y_,intDsize);
                }
@@ -154,7 +165,7 @@ const cl_I ash (const cl_I& x, const cl_I& y)
                var uintD* MSDptr;
                var uintC len;
                I_to_NDS(x, MSDptr=,len=,); // DS zu x bilden.
-               if (k>=len) goto sign; // -y >= intDsize*len -> Vorzeichen von x zurück
+               if (k>=len) goto sign; // -y >= intDsize*len -> Vorzeichen von x zurück
                len -= k; // rechte k Digits einfach streichen
                // Noch ist len>0. Um i Bits nach rechts schieben:
                if (!(i==0)) // Bei i>0: