1 // cl_I equal_hashcode().
2
3 // General includes.
4 #include "base/cl_sysdep.h"
5
6 // Specification.
7 #include "cln/integer.h"
8
9
10 // Implementation.
11
12 #include "base/cl_N.h"
13 #include "integer/cl_I.h"
14
15 namespace cln {
16
equal_hashcode(const cl_FN & x)17 static 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
equal_hashcode(const cl_BN & x)42 static 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
CL_INLINE_DECL(equal_hashcode)131 CL_INLINE uint32 CL_INLINE_DECL(equal_hashcode) (const cl_I& x)
132 {
133 if (fixnump(x)) {
134 DeclareType(cl_FN,x);
135 return equal_hashcode(x);
136 } else {
137 DeclareType(cl_BN,x);
138 return equal_hashcode(x);
139 }
140 }
141
142 } // namespace cln
143