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