| File: | subcmd/unitools/dword.c |
| Warning: | line 144, column 3 Value stored to 'ql' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /****************************************************************************** |
| 2 | * |
| 3 | * :: Double Word operations. |
| 4 | * |
| 5 | *****************************************************************************/ |
| 6 | |
| 7 | /* #ifdef FOAM_RTS */ |
| 8 | #include "axlgen.h" |
| 9 | #include "bigint.h" |
| 10 | #include "optcfg.h" |
| 11 | typedef ULong BIntD; /* To contain two BInt digits. */ |
| 12 | |
| 13 | #define BINT_LG_RADIX((8 * sizeof(BIntS))) (bitsizeof(BIntS)(8 * sizeof(BIntS))) |
| 14 | #define BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))) (((unsigned long) 1) << BINT_LG_RADIX((8 * sizeof(BIntS)))) |
| 15 | |
| 16 | #define DivideDouble(q, r, nh, nl, d){ BIntD n_ = (BIntD)(nh)*(BIntD)(((unsigned long) 1) << ((8 * sizeof(BIntS)))) + (nl); BIntD d_ = (d); (q) = n_ / d_ ; (r) = n_ % d_; } { \ |
| 17 | BIntD n_ = (BIntD)(nh)*(BIntD)BINT_RADIX(((unsigned long) 1) << ((8 * sizeof(BIntS)))) + (nl);\ |
| 18 | BIntD d_ = (d); \ |
| 19 | (q) = n_ / d_; \ |
| 20 | (r) = n_ % d_; \ |
| 21 | } |
| 22 | |
| 23 | #ifdef BIGINT_TEST_BASE |
| 24 | # define BASE_BITS(8 * sizeof(unsigned long)) 6 |
| 25 | # define __TEST_BASE (1L << BASE_BITS(8 * sizeof(unsigned long))) |
| 26 | # define BASE_MINUS_1(9223372036854775807L *2UL+1UL) (__TEST_BASE - 1) |
| 27 | # define MODB(x)(x) ((x) % __TEST_BASE) |
| 28 | #else |
| 29 | # define BASE_MINUS_1(9223372036854775807L *2UL+1UL) ULONG_MAX(9223372036854775807L *2UL+1UL) |
| 30 | # define BASE_BITS(8 * sizeof(unsigned long)) (CHAR_BIT8 * sizeof(unsigned long)) |
| 31 | # define MODB(x)(x) (x) |
| 32 | #endif |
| 33 | |
| 34 | #define BASE_BITS_2((8 * sizeof(unsigned long))/2) (BASE_BITS(8 * sizeof(unsigned long))/2) |
| 35 | #define BASE_ROOT(1L << (((8 * sizeof(unsigned long))/2))) (1L << (BASE_BITS_2((8 * sizeof(unsigned long))/2))) |
| 36 | #define COMPL(x)((9223372036854775807L *2UL+1UL) - (x)) (BASE_MINUS_1(9223372036854775807L *2UL+1UL) - (x)) |
| 37 | #define LO_HALF_LO(x)((x) & ((1L << (((8 * sizeof(unsigned long))/2)))-1 )) ((x) & (BASE_ROOT(1L << (((8 * sizeof(unsigned long))/2)))-1)) |
| 38 | #define HI_HALF_LO(x)((x) >> ((8 * sizeof(unsigned long))/2)) ((x) >> BASE_BITS_2((8 * sizeof(unsigned long))/2)) |
| 39 | #define LO_HALF_HI(x)(((x) & ((1L << (((8 * sizeof(unsigned long))/2)))- 1)) << ((8 * sizeof(unsigned long))/2)) (((x) & (BASE_ROOT(1L << (((8 * sizeof(unsigned long))/2)))-1)) << BASE_BITS_2((8 * sizeof(unsigned long))/2)) |
| 40 | #define HI_HALF_HI(x)(((x) >> (8 * sizeof(unsigned long))) << ((8 * sizeof (unsigned long))/2)) (((x) >> BASE_BITS(8 * sizeof(unsigned long))) << BASE_BITS_2((8 * sizeof(unsigned long))/2)) |
| 41 | #define COMBINE(h, l)(((h) << ((8 * sizeof(unsigned long))/2)) | (l)) (((h) << BASE_BITS_2((8 * sizeof(unsigned long))/2)) | (l)) |
| 42 | #define HI_BIT(n)(((n) >> ((8 * sizeof(unsigned long))-1)) & 1) (((n) >> (BASE_BITS(8 * sizeof(unsigned long))-1)) & 1) |
| 43 | |
| 44 | |
| 45 | void |
| 46 | xxTestGtDouble(int *pb, ULong AH, ULong AL, ULong BH, ULong BL) |
| 47 | { |
| 48 | *pb = AH > BH || (AH == BH && AL > BL); |
| 49 | } |
| 50 | |
| 51 | #ifndef OPT_NoDoubleOps |
| 52 | |
| 53 | void |
| 54 | xxTimesDouble(ULong *pH, ULong *pL, ULong A, ULong B) |
| 55 | { |
| 56 | ULong Ah, Al, Bh, Bl; |
| 57 | ULong H, M, N, L; |
| 58 | ULong Mh, Mx, Nh, Nx; |
| 59 | ULong T; |
| 60 | |
| 61 | Ah = HI_HALF_LO(A)((A) >> ((8 * sizeof(unsigned long))/2)); |
| 62 | Al = LO_HALF_LO(A)((A) & ((1L << (((8 * sizeof(unsigned long))/2)))-1 )); |
| 63 | Bh = HI_HALF_LO(B)((B) >> ((8 * sizeof(unsigned long))/2)); |
| 64 | Bl = LO_HALF_LO(B)((B) & ((1L << (((8 * sizeof(unsigned long))/2)))-1 )); |
| 65 | |
| 66 | H = MODB(Ah * Bh)(Ah * Bh); |
| 67 | M = MODB(Al * Bh)(Al * Bh); |
| 68 | N = MODB(Ah * Bl)(Ah * Bl); |
| 69 | L = MODB(Al * Bl)(Al * Bl); |
| 70 | |
| 71 | Mh = HI_HALF_LO(M)((M) >> ((8 * sizeof(unsigned long))/2)); |
| 72 | Mx = LO_HALF_HI(M)(((M) & ((1L << (((8 * sizeof(unsigned long))/2)))- 1)) << ((8 * sizeof(unsigned long))/2)); |
| 73 | Nh = HI_HALF_LO(N)((N) >> ((8 * sizeof(unsigned long))/2)); |
| 74 | Nx = LO_HALF_HI(N)(((N) & ((1L << (((8 * sizeof(unsigned long))/2)))- 1)) << ((8 * sizeof(unsigned long))/2)); |
| 75 | |
| 76 | T = L; |
| 77 | L = MODB(L + Mx)(L + Mx); |
| 78 | H = MODB(H + (L < T))(H + (L < T)); |
| 79 | H = MODB(H + Mh)(H + Mh); |
| 80 | |
| 81 | T = L; |
| 82 | L = MODB(L + Nx)(L + Nx); |
| 83 | H = MODB(H + (L < T))(H + (L < T)); |
| 84 | H = MODB(H + Nh)(H + Nh); |
| 85 | |
| 86 | *pH= H; |
| 87 | *pL= L; |
| 88 | } |
| 89 | #endif |
| 90 | |
| 91 | void |
| 92 | xxPlusStep(ULong *pko, ULong *pr, ULong a, ULong b, ULong ki) |
| 93 | { |
| 94 | ULong ko, r; |
| 95 | |
| 96 | r = MODB(a + b)(a + b); |
| 97 | ko = r < a; |
| 98 | r = MODB(r + ki)(r + ki); |
| 99 | ko+= r < ki; |
| 100 | |
| 101 | *pko = ko; |
| 102 | *pr = r; |
| 103 | } |
| 104 | |
| 105 | #define minusStep(pkp1out,pr,a,b,kp1in)plusStep(pkp1out,pr,a,((9223372036854775807L *2UL+1UL) - (b)) ,kp1in) plusStep(pkp1out,pr,a,COMPL(b)((9223372036854775807L *2UL+1UL) - (b)),kp1in) |
| 106 | |
| 107 | void |
| 108 | xxTimesStep(ULong *pko, ULong *pr, ULong a, ULong b, ULong c, ULong ki) |
| 109 | { |
| 110 | ULong h, l, k, r; |
| 111 | |
| 112 | xxTimesDouble(&h, &l, a, b); |
| 113 | |
| 114 | r = MODB(l + c)(l + c); |
| 115 | k = r < l; |
| 116 | r = MODB(r + ki)(r + ki); |
| 117 | k += r < ki; |
| 118 | *pr = r; |
| 119 | r = MODB(h + k)(h + k); |
| 120 | *pko = r; |
| 121 | } |
| 122 | |
| 123 | #ifndef OPT_NoDoubleOps |
| 124 | |
| 125 | void |
| 126 | xxDivideDouble(ULong *pqh, ULong *pql, ULong *pr, |
| 127 | ULong nh, ULong nl, ULong d) |
| 128 | { |
| 129 | ULong qh, ql, rh, rl; /* results */ |
| 130 | ULong qrh,rrh,qrl,rrl,qB,rB; /* quo/rem rh, rl, base */ |
| 131 | ULong Bd; |
| 132 | ULong th, tl; /* temporaries */ |
| 133 | |
| 134 | |
| 135 | if (d == 1) { |
| 136 | *pqh = nh; *pql = nl; |
| 137 | *pr = 0; |
| 138 | return; |
| 139 | } |
| 140 | if (d < BASE_ROOT(1L << (((8 * sizeof(unsigned long))/2)))) { |
| 141 | ULong r = 0, th,tl; |
| 142 | DivideDouble(th, r, r, HI_HALF_LO(nh), d){ BIntD n_ = (BIntD)(r)*(BIntD)(((unsigned long) 1) << ( (8 * sizeof(BIntS)))) + (((nh) >> ((8 * sizeof(unsigned long))/2))); BIntD d_ = (d); (th) = n_ / d_; (r) = n_ % d_; }; |
| 143 | DivideDouble(tl, r, r, LO_HALF_LO(nh), d){ BIntD n_ = (BIntD)(r)*(BIntD)(((unsigned long) 1) << ( (8 * sizeof(BIntS)))) + (((nh) & ((1L << (((8 * sizeof (unsigned long))/2)))-1))); BIntD d_ = (d); (tl) = n_ / d_; ( r) = n_ % d_; }; |
| 144 | ql = COMBINE(th, tl)(((th) << ((8 * sizeof(unsigned long))/2)) | (tl)); |
Value stored to 'ql' is never read | |
| 145 | DivideDouble(th, r, r, HI_HALF_LO(nl), d){ BIntD n_ = (BIntD)(r)*(BIntD)(((unsigned long) 1) << ( (8 * sizeof(BIntS)))) + (((nl) >> ((8 * sizeof(unsigned long))/2))); BIntD d_ = (d); (th) = n_ / d_; (r) = n_ % d_; }; |
| 146 | DivideDouble(tl, r, r, LO_HALF_LO(nl), d){ BIntD n_ = (BIntD)(r)*(BIntD)(((unsigned long) 1) << ( (8 * sizeof(BIntS)))) + (((nl) & ((1L << (((8 * sizeof (unsigned long))/2)))-1))); BIntD d_ = (d); (tl) = n_ / d_; ( r) = n_ % d_; }; |
| 147 | ql = COMBINE(th, tl)(((th) << ((8 * sizeof(unsigned long))/2)) | (tl)); |
| 148 | |
| 149 | *pqh = 0; |
| 150 | *pql = ql; |
| 151 | *pr = r; |
| 152 | return; |
| 153 | } |
| 154 | /* |
| 155 | * B-d = (B-1) - d + 1 = q' d + r' => B = (q' + 1) d + r' |
| 156 | */ |
| 157 | Bd = COMPL(d-1)((9223372036854775807L *2UL+1UL) - (d-1)); |
| 158 | qB = Bd / d + 1; |
| 159 | rB = Bd % d; |
| 160 | |
| 161 | qh = 0; ql = 0; |
| 162 | rh = nh; rl = nl; |
| 163 | |
| 164 | while (rh != 0 || rl >= d) { |
| 165 | |
| 166 | qrh = rh / d; rrh = rh % d; |
| 167 | qrl = rl / d; rrl = rl % d; |
| 168 | |
| 169 | /* [qh,ql] += qrh*B + rrh*qB + qrl */ |
| 170 | /* [rh,rl] = rrh*rB + rrl */ |
| 171 | |
| 172 | /* |
| 173 | * xxTimesDouble(&h, &l, rrh, qB); |
| 174 | * plusStep (&k, &tl, l, qrl, 0); |
| 175 | * plusStep (&k, &th, h, k, 0); |
| 176 | * plusStep (&k, &ql, tl, ql, 0); |
| 177 | * plusStep (&k, &qh, th, qh, qrh+k); |
| 178 | */ |
| 179 | xxTimesDouble(&th, &tl, rrh, qB); |
| 180 | tl = MODB(tl + qrl)(tl + qrl); |
| 181 | th = MODB(th + (tl < qrl))(th + (tl < qrl)); |
| 182 | ql = MODB(ql + tl)(ql + tl); |
| 183 | qh = MODB(qh + (ql < tl))(qh + (ql < tl)); |
| 184 | qh = MODB(qh + th)(qh + th); |
| 185 | qh = MODB(qh + qrh)(qh + qrh); |
| 186 | |
| 187 | /* |
| 188 | * xxTimesStep(&rh, &rl, rrh, rB, rrl, 0); |
| 189 | */ |
| 190 | xxTimesDouble(&th, &tl, rrh, rB); |
| 191 | rl = MODB(tl + rrl)(tl + rrl); |
| 192 | rh = MODB(th + (rl < rrl))(th + (rl < rrl)); |
| 193 | } |
| 194 | |
| 195 | *pqh = qh; *pql = ql; |
| 196 | *pr = rl; |
| 197 | |
| 198 | } |
| 199 | |
| 200 | |
| 201 | /* As above, but no quotient */ |
| 202 | ULong |
| 203 | xxModDouble(ULong nh, ULong nl, ULong d) |
| 204 | { |
| 205 | ULong qh, ql, rh, rl; /* results */ |
| 206 | ULong rrh,rrl,qB,rB; /* quo/rem rh, rl, base */ |
| 207 | ULong Bd; |
| 208 | ULong th, tl; /* temporaries */ |
| 209 | |
| 210 | if (d == 1) { |
| 211 | return 0; |
| 212 | } |
| 213 | |
| 214 | if (d < BASE_ROOT(1L << (((8 * sizeof(unsigned long))/2)))) { |
| 215 | ULong r = 0, tmp; |
| 216 | DivideDouble(tmp, r, r, HI_HALF_LO(nh), d){ BIntD n_ = (BIntD)(r)*(BIntD)(((unsigned long) 1) << ( (8 * sizeof(BIntS)))) + (((nh) >> ((8 * sizeof(unsigned long))/2))); BIntD d_ = (d); (tmp) = n_ / d_; (r) = n_ % d_; }; |
| 217 | DivideDouble(tmp, r, r, LO_HALF_LO(nh), d){ BIntD n_ = (BIntD)(r)*(BIntD)(((unsigned long) 1) << ( (8 * sizeof(BIntS)))) + (((nh) & ((1L << (((8 * sizeof (unsigned long))/2)))-1))); BIntD d_ = (d); (tmp) = n_ / d_; ( r) = n_ % d_; }; |
| 218 | DivideDouble(tmp, r, r, HI_HALF_LO(nl), d){ BIntD n_ = (BIntD)(r)*(BIntD)(((unsigned long) 1) << ( (8 * sizeof(BIntS)))) + (((nl) >> ((8 * sizeof(unsigned long))/2))); BIntD d_ = (d); (tmp) = n_ / d_; (r) = n_ % d_; }; |
| 219 | DivideDouble(tmp, r, r, LO_HALF_LO(nl), d){ BIntD n_ = (BIntD)(r)*(BIntD)(((unsigned long) 1) << ( (8 * sizeof(BIntS)))) + (((nl) & ((1L << (((8 * sizeof (unsigned long))/2)))-1))); BIntD d_ = (d); (tmp) = n_ / d_; ( r) = n_ % d_; }; |
| 220 | |
| 221 | return r; |
| 222 | } |
| 223 | |
| 224 | /* |
| 225 | * B-d = (B-1) - d + 1 = q' d + r' => B = (q' + 1) d + r' |
| 226 | */ |
| 227 | Bd = COMPL(d-1)((9223372036854775807L *2UL+1UL) - (d-1)); |
| 228 | qB = Bd / d + 1; |
| 229 | rB = Bd % d; |
| 230 | |
| 231 | qh = 0; ql = 0; |
| 232 | rh = nh; rl = nl; |
| 233 | |
| 234 | while (rh != 0 || rl >= d) { |
| 235 | |
| 236 | rrh = rh % d; |
| 237 | rrl = rl % d; |
| 238 | |
| 239 | /* |
| 240 | * xxTimesStep(&rh, &rl, rrh, rB, rrl, 0); |
| 241 | */ |
| 242 | xxTimesDouble(&th, &tl, rrh, rB); |
| 243 | rl = MODB(tl + rrl)(tl + rrl); |
| 244 | rh = MODB(th + (rl < rrl))(th + (rl < rrl)); |
| 245 | } |
| 246 | |
| 247 | return rl; |
| 248 | } |
| 249 | |
| 250 | #endif |
| 251 | |
| 252 | #if defined(BIGINT_TEST_BASE) |
| 253 | |
| 254 | #define BASE __TEST_BASE |
| 255 | main() |
| 256 | { |
| 257 | BIntS a, b, c, d, h, l, k; |
| 258 | BIntS r1, r2; |
| 259 | int t; |
| 260 | |
| 261 | for (a = 0; a < BASE; a++) { |
| 262 | for (b = 0; b < BASE; b++) { |
| 263 | printf("."); |
| 264 | |
| 265 | timesDouble(&h, &l, a, b); |
| 266 | r1 = h * BASE + l; |
| 267 | r2 = a * b; |
| 268 | if (h >= BASE || l >= BASE || r1 != r2) |
| 269 | printf("%d * %d fails\n", a, b); |
| 270 | |
| 271 | plusStep(&h, &l, a, b, int0((int) 0)); |
| 272 | r1 = h * BASE + l; |
| 273 | r2 = a + b + 0; |
| 274 | if (h >= BASE || l >= BASE || r1 != r2) |
| 275 | printf("%d + %d + 0 fails\n", a, b); |
| 276 | |
| 277 | plusStep(&h, &l, a, b, 1); |
| 278 | r1 = h * BASE + l; |
| 279 | r2 = a + b + 1; |
| 280 | if (h >= BASE || l >= BASE || r1 != r2) |
| 281 | printf("%d + %d + 1 fails\n", a, b); |
| 282 | |
| 283 | minusStep(&h, &l, a, b, 1)plusStep(&h,&l,a,((9223372036854775807L *2UL+1UL) - ( b)),1); |
| 284 | r1 = (h-1) * BASE + l; |
| 285 | r2 = a - b - 0; |
| 286 | if (h >= BASE || l >= BASE || r1 != r2) |
| 287 | printf("%d - %d - 0 fails\n", a, b); |
| 288 | |
| 289 | minusStep(&h, &l, a, b, int0)plusStep(&h,&l,a,((9223372036854775807L *2UL+1UL) - ( b)),((int) 0)); |
| 290 | r1 = (h-1) * BASE + l; |
| 291 | r2 = a - b - 1; |
| 292 | if (h >= BASE || l >= BASE || r1 != r2) |
| 293 | printf("%d - %d - 1 fails\n", a, b); |
| 294 | |
| 295 | for (c = 0; c < BASE; c++) { |
| 296 | for (d = 0; d < BASE; d++) { |
| 297 | |
| 298 | timesStep(&h, &l, a, b, c, d); |
| 299 | r1 = h * BASE + l; |
| 300 | r2 = a * b + c + d; |
| 301 | if (h >= BASE || l >= BASE || r1 != r2) |
| 302 | printf("%d * %d + %d + %d fails\n", a, b, c, d); |
| 303 | |
| 304 | testGtDouble(&t, a, b, c, d); |
| 305 | r1 = t; |
| 306 | r2 = (a * BASE + b) > (c * BASE + d); |
| 307 | if (r1 != r2) |
| 308 | printf("%d,%d > %d,%d fails\n", a, b, c, d); |
| 309 | } |
| 310 | } |
| 311 | for (c = 1; c < BASE; c++) { |
| 312 | divideDouble(&h, &l, &k, a, b, c); |
| 313 | |
| 314 | r1 = h * BASE + l; |
| 315 | r2 =(a * BASE + b) / c; |
| 316 | if (h >= BASE || l >= BASE || r1 != r2) { |
| 317 | printf("(%d,%d) / %d fails\n", a, b, c); |
| 318 | divideDouble(&h, &l, &k, a, b, c); |
| 319 | } |
| 320 | |
| 321 | r1 = k; |
| 322 | r2 =(a * BASE + b) % c; |
| 323 | if (k >= BASE || r1 != r2) { |
| 324 | printf("(%d,%d) %% %d fails\n", a, b, c); |
| 325 | divideDouble(&h, &l, &k, a, b, c); |
| 326 | } |
| 327 | } |
| 328 | |
| 329 | } |
| 330 | printf("\n"); |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | #endif /* (BIGINT_TEST_WHOLE_WORDS) */ |