]> www.ginac.de Git - cln.git/blob - src/integer/bitwise/cl_I_ldbxtest.cc
Avoid some "suggest explicit braces to avoid ambiguous ‘else’" warnings.
[cln.git] / src / integer / bitwise / cl_I_ldbxtest.cc
1 // ldb_extract_test().
2
3 // General includes.
4 #include "base/cl_sysdep.h"
5
6 // Specification.
7 #include "integer/bitwise/cl_I_byte.h"
8
9
10 // Implementation.
11
12 #include "cln/integer.h"
13 #include "integer/cl_I.h"
14 #include "base/digitseq/cl_DS.h"
15
16 namespace cln {
17
18 bool ldb_extract_test (const cl_I& x, uintC p, uintC q)
19     { var const uintD* MSDptr;
20       var uintC len;
21       var const uintD* LSDptr;
22       I_to_NDS_nocopy(x, MSDptr=,len=,LSDptr=,true, { return false; } ); // NDS zu x bilden
23       // MSDptr erhöhen und len erniedrigen, so daß len = ceiling(q/intDsize) wird:
24       { var uintC qD = ceiling(q,intDsize); // ceiling(q/intDsize)
25         // wegen q<=l ist qD = ceiling(q/intDsize) <= ceiling((l+1)/intDsize) = len, also
26         // paßt qD ebenso wie len in ein uintC.
27         MSDptr = MSDptr mspop (len - qD); // MSDptr um len-qD Digits erhöhen
28         len = qD; // len um len-qD erniedrigen
29       }
30       // LSDptr und len um floor(p/intDsize) erniedrigen:
31       { var uintC pD = p/intDsize; // floor(p/intDsize)
32         LSDptr = LSDptr lspop pD;
33         len -= pD;
34       }
35       // Jetzt enthält MSDptr/len/LSDptr genau die maßgeblichen Digits.
36       if (len==0) return false; // len=0 -> keine Bits abzutesten
37       q = ((q-1)%intDsize); // q := intDsize - (intDsize*ceiling(q/intDsize) - q) - 1
38       p = p%intDsize; // p := p - intDsize*floor(p/intDsize)
39       // Jetzt ist 0 <= q < intDsize, 0 <= p < intDsize.
40       // Vom ersten Digit müssen die vorderen intDsize-1-q Bits unberücksichtigt bleiben.
41       // Ein AND 2^(q+1)-1 erreicht dies.
42       // Vom letzten Digit müssen die hinteren p Bits unberücksichtigt bleiben.
43       // Ein AND -2^p erreicht dies.
44       if (--len==0) {
45         // 1 Digit maßgeblich, wird von beiden Seiten angeschnitten:
46         // Ein AND 2^(q+1)-2^p erreicht dies.
47         if (!(((uintD)(bitm(q+1)-bit(p)) & mspref(MSDptr,0)) == 0))
48           return true;
49         else
50           return false;
51       }
52       // mindestens 2 Digits. Teste erst die Randdigits, dann die inneren:
53       if (!(((msprefnext(MSDptr) & (uintD)(bitm(q+1)-1)) == 0) &&
54             ((lsprefnext(LSDptr) & (uintD)(minus_bit(p))) == 0)
55          ) )
56         return true;
57       len--; // die beiden Randdigits sind jetzt abgezogen.
58       if (DS_test_loop(MSDptr,len,LSDptr)) { return true; } else { return false; }
59     }
60
61 }  // namespace cln