]> www.ginac.de Git - cln.git/blob - src/integer/misc/cl_I_eqhashcode.cc
* */*: Convert encoding from ISO 8859-1 to UTF-8.
[cln.git] / src / integer / misc / cl_I_eqhashcode.cc
1 // cl_I equal_hashcode().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cln/integer.h"
8
9
10 // Implementation.
11
12 #include "cl_N.h"
13 #include "cl_I.h"
14
15 namespace cln {
16
17 inline uint32 equal_hashcode (const cl_FN& x)
18 {
19         var cl_signean sign;
20         var uintV x_ = FN_to_V(x); // x als intVsize-Bit-Zahl
21         if (FN_V_minusp(x,(sintV)x_)) {
22                 x_ = -x_;
23                 sign = -1;
24         } else {
25                 sign = 0;
26                 if (x_ == 0)
27                         return 0;
28         }
29         var uintL s;
30         #if (intVsize > 32)
31         integerlength64(x_, s = 64 - );
32         var uint32 msd = (x_ << s) >> 32;
33         var sintL exp = 64-s;
34         #else
35         integerlength32(x_, s = 32 - );
36         var uint32 msd = x_ << s;
37         var sintL exp = 32-s;
38         #endif
39         return equal_hashcode_low(msd,exp,sign);
40 }
41
42 inline uint32 equal_hashcode (const cl_BN& x)
43 {
44         var const uintD* MSDptr;
45         var uintC len;
46         BN_to_NDS_nocopy(x, MSDptr = , len = ,);
47         // Nicht alle führenden intDsize+1 Bits sind gleich.
48 #if (intDsize==64)
49         var uint64 msd = mspref(MSDptr,0);
50         var uint64 msd2 = (len >= 2 ? mspref(MSDptr,1) : 0);
51         var cl_signean sign;
52         if ((sint64)msd < 0) { // falls <0, negieren
53                 sign = -1;
54                 // msd|msd2 := - msd|msd2 - (1 falls noch weitere Bits /= 0)
55                 msd = ~msd; msd2 = ~msd2;
56                 if ((len <= 2)
57                     || !test_loop_msp(MSDptr mspop 2, len - 2)
58                    ) {
59                         msd2++;
60                         if (msd2 == 0)
61                                 msd++;
62                 }
63         } else {
64                 sign = 0;
65         }
66         var sintC exp = len * intDsize;
67         // Nicht alle führenden 65 Bits sind =0.
68         if (msd==0) {
69                 msd = msd2;
70                 exp -= 64;
71         } else {
72                 var uintL s;
73                 integerlength64(msd, s = 64 - );
74                 if (s > 0)
75                         msd = (msd << s) | (msd2 >> (64-s));
76                 exp -= s;
77         }
78         return equal_hashcode_low((uint32)(msd>>32),exp,sign);
79 #else // (intDsize<=32)
80         var uint32 msd;
81         var uint32 msd2;
82         if (len >= 64/intDsize) {
83                 msd = get_32_Dptr(MSDptr);
84                 msd2 = get_32_Dptr(MSDptr mspop 32/intDsize);
85         } elif (len > 32/intDsize) {
86                 msd = get_32_Dptr(MSDptr);
87                 msd2 = get_max32_Dptr(intDsize*len-32, MSDptr mspop 32/intDsize)
88                        << (64-intDsize*len);
89         } elif ((32/intDsize == 1) || (len == 32/intDsize)) {
90                 msd = get_32_Dptr(MSDptr);
91                 msd2 = 0;
92         } else { // (len > 0) && (len < 32/intDsize)
93                 msd = get_max32_Dptr(intDsize*len,MSDptr) << (32-intDsize*len);
94                 msd2 = 0;
95         }
96         var cl_signean sign;
97         if ((sint32)msd < 0) { // falls <0, negieren
98                 sign = -1;
99                 // msd|msd2 := - msd|msd2 - (1 falls noch weitere Bits /= 0)
100                 msd = ~msd; msd2 = ~msd2;
101                 if ((len <= 64/intDsize)
102                     || !test_loop_msp(MSDptr mspop 64/intDsize, len - 64/intDsize)
103                    ) {
104                         msd2++;
105                         if (msd2 == 0)
106                                 msd++;
107                 }
108         } else {
109                 sign = 0;
110         }
111         var sintC exp = len * intDsize;
112         // Nicht alle führenden intDsize+1 Bits sind =0.
113         // Wegen intDsize<=32: Nicht alle führenden 33 Bits sind =0.
114         if (msd==0) {
115                 msd = msd2;
116                 exp -= 32;
117         }
118         // Nicht alle führenden 32 Bits sind =0.
119         // Führendes Bit auf 1 normalisieren:
120         else {
121                 var uintL s;
122                 integerlength32(msd, s = 32 - );
123                 if (s > 0)
124                         msd = (msd << s) | (msd2 >> (32-s));
125                 exp -= s;
126         }
127         return equal_hashcode_low(msd,exp,sign);
128 #endif
129 }
130
131 MAYBE_INLINE
132 uint32 equal_hashcode (const cl_I& x)
133 {
134         if (fixnump(x)) {
135                 DeclareType(cl_FN,x);
136                 return equal_hashcode(x);
137         } else {
138                 DeclareType(cl_BN,x);
139                 return equal_hashcode(x);
140         }
141 }
142
143 }  // namespace cln