1 /* DIGIT.C - digit arithmetic routines
4 /* Copyright (C) RSA Laboratories, a division of RSA Data Security,
5 Inc., created 1991. All rights reserved.
13 /* Computes a = b * c, where b and c are digits.
17 void NN_DigitMult (a, b, c)
21 NN_HALF_DIGIT bHigh, bLow, cHigh, cLow;
23 bHigh = (NN_HALF_DIGIT)HIGH_HALF (b);
24 bLow = (NN_HALF_DIGIT)LOW_HALF (b);
25 cHigh = (NN_HALF_DIGIT)HIGH_HALF (c);
26 cLow = (NN_HALF_DIGIT)LOW_HALF (c);
28 a[0] = (NN_DIGIT)bLow * (NN_DIGIT)cLow;
29 t = (NN_DIGIT)bLow * (NN_DIGIT)cHigh;
30 u = (NN_DIGIT)bHigh * (NN_DIGIT)cLow;
31 a[1] = (NN_DIGIT)bHigh * (NN_DIGIT)cHigh;
34 a[1] += TO_HIGH_HALF (1);
39 a[1] += HIGH_HALF (t);
42 /* Sets a = b / c, where a and c are digits.
45 Assumes b[1] < c and HIGH_HALF (c) > 0. For efficiency, c should be
48 void NN_DigitDiv (a, b, c)
52 NN_HALF_DIGIT aHigh, aLow, cHigh, cLow;
54 cHigh = (NN_HALF_DIGIT)HIGH_HALF (c);
55 cLow = (NN_HALF_DIGIT)LOW_HALF (c);
60 /* Underestimate high half of quotient and subtract.
62 if (cHigh == MAX_NN_HALF_DIGIT)
63 aHigh = (NN_HALF_DIGIT)HIGH_HALF (t[1]);
65 aHigh = (NN_HALF_DIGIT)(t[1] / (cHigh + 1));
66 u = (NN_DIGIT)aHigh * (NN_DIGIT)cLow;
67 v = (NN_DIGIT)aHigh * (NN_DIGIT)cHigh;
68 if ((t[0] -= TO_HIGH_HALF (u)) > (MAX_NN_DIGIT - TO_HIGH_HALF (u)))
70 t[1] -= HIGH_HALF (u);
75 while ((t[1] > cHigh) ||
76 ((t[1] == cHigh) && (t[0] >= TO_HIGH_HALF (cLow)))) {
77 if ((t[0] -= TO_HIGH_HALF (cLow)) > MAX_NN_DIGIT - TO_HIGH_HALF (cLow))
83 /* Underestimate low half of quotient and subtract.
85 if (cHigh == MAX_NN_HALF_DIGIT)
86 aLow = (NN_HALF_DIGIT)LOW_HALF (t[1]);
89 (NN_HALF_DIGIT)((TO_HIGH_HALF (t[1]) + HIGH_HALF (t[0])) / (cHigh + 1));
90 u = (NN_DIGIT)aLow * (NN_DIGIT)cLow;
91 v = (NN_DIGIT)aLow * (NN_DIGIT)cHigh;
92 if ((t[0] -= u) > (MAX_NN_DIGIT - u))
94 if ((t[0] -= TO_HIGH_HALF (v)) > (MAX_NN_DIGIT - TO_HIGH_HALF (v)))
96 t[1] -= HIGH_HALF (v);
100 while ((t[1] > 0) || ((t[1] == 0) && t[0] >= c)) {
101 if ((t[0] -= c) > (MAX_NN_DIGIT - c))
106 *a = TO_HIGH_HALF (aHigh) + aLow;