OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / libcore / luni / src / main / native / cbigint.cpp
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17
18 #include <string.h>
19 #include "cbigint.h"
20
21 #if defined(__linux__) || defined(FREEBSD) || defined(ZOS) || defined(MACOSX) || defined(AIX)
22 #define USE_LL
23 #endif
24
25 #if __BYTE_ORDER == __LITTLE_ENDIAN
26 #define at(i) (i)
27 #else
28 #define at(i) ((i)^1)
29 /* the sequence for halfAt is -1, 2, 1, 4, 3, 6, 5, 8... */
30 /* and it should correspond to 0, 1, 2, 3, 4, 5, 6, 7... */
31 #define halfAt(i) (-((-(i)) ^ 1))
32 #endif
33
34 #define HIGH_IN_U64(u64) ((u64) >> 32)
35 #if defined(USE_LL)
36 #define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFFLL)
37 #else
38 #if defined(USE_L)
39 #define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFFL)
40 #else
41 #define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFF)
42 #endif /* USE_L */
43 #endif /* USE_LL */
44
45 #if defined(USE_LL)
46 #define TEN_E1 (0xALL)
47 #define TEN_E2 (0x64LL)
48 #define TEN_E3 (0x3E8LL)
49 #define TEN_E4 (0x2710LL)
50 #define TEN_E5 (0x186A0LL)
51 #define TEN_E6 (0xF4240LL)
52 #define TEN_E7 (0x989680LL)
53 #define TEN_E8 (0x5F5E100LL)
54 #define TEN_E9 (0x3B9ACA00LL)
55 #define TEN_E19 (0x8AC7230489E80000LL)
56 #else
57 #if defined(USE_L)
58 #define TEN_E1 (0xAL)
59 #define TEN_E2 (0x64L)
60 #define TEN_E3 (0x3E8L)
61 #define TEN_E4 (0x2710L)
62 #define TEN_E5 (0x186A0L)
63 #define TEN_E6 (0xF4240L)
64 #define TEN_E7 (0x989680L)
65 #define TEN_E8 (0x5F5E100L)
66 #define TEN_E9 (0x3B9ACA00L)
67 #define TEN_E19 (0x8AC7230489E80000L)
68 #else
69 #define TEN_E1 (0xA)
70 #define TEN_E2 (0x64)
71 #define TEN_E3 (0x3E8)
72 #define TEN_E4 (0x2710)
73 #define TEN_E5 (0x186A0)
74 #define TEN_E6 (0xF4240)
75 #define TEN_E7 (0x989680)
76 #define TEN_E8 (0x5F5E100)
77 #define TEN_E9 (0x3B9ACA00)
78 #define TEN_E19 (0x8AC7230489E80000)
79 #endif /* USE_L */
80 #endif /* USE_LL */
81
82 #define TIMES_TEN(x) (((x) << 3) + ((x) << 1))
83 #define bitSection(x, mask, shift) (((x) & (mask)) >> (shift))
84 #define CREATE_DOUBLE_BITS(normalizedM, e) (((normalizedM) & MANTISSA_MASK) | ((static_cast<uint64_t>((e) + E_OFFSET)) << 52))
85
86 #if defined(USE_LL)
87 #define MANTISSA_MASK (0x000FFFFFFFFFFFFFLL)
88 #define EXPONENT_MASK (0x7FF0000000000000LL)
89 #define NORMAL_MASK (0x0010000000000000LL)
90 #define SIGN_MASK (0x8000000000000000LL)
91 #else
92 #if defined(USE_L)
93 #define MANTISSA_MASK (0x000FFFFFFFFFFFFFL)
94 #define EXPONENT_MASK (0x7FF0000000000000L)
95 #define NORMAL_MASK (0x0010000000000000L)
96 #define SIGN_MASK (0x8000000000000000L)
97 #else
98 #define MANTISSA_MASK (0x000FFFFFFFFFFFFF)
99 #define EXPONENT_MASK (0x7FF0000000000000)
100 #define NORMAL_MASK (0x0010000000000000)
101 #define SIGN_MASK (0x8000000000000000)
102 #endif /* USE_L */
103 #endif /* USE_LL */
104
105 #define E_OFFSET (1075)
106
107 #define FLOAT_MANTISSA_MASK (0x007FFFFF)
108 #define FLOAT_EXPONENT_MASK (0x7F800000)
109 #define FLOAT_NORMAL_MASK   (0x00800000)
110 #define FLOAT_E_OFFSET (150)
111
112 int32_t
113 simpleAddHighPrecision (uint64_t * arg1, int32_t length, uint64_t arg2)
114 {
115   /* assumes length > 0 */
116   int32_t index = 1;
117
118   *arg1 += arg2;
119   if (arg2 <= *arg1)
120     return 0;
121   else if (length == 1)
122     return 1;
123
124   while (++arg1[index] == 0 && ++index < length);
125
126   return index == length;
127 }
128
129 int32_t
130 addHighPrecision (uint64_t * arg1, int32_t length1, uint64_t * arg2, int32_t length2)
131 {
132   /* addition is limited by length of arg1 as it this function is
133    * storing the result in arg1 */
134   /* fix for cc (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7): code generated does not
135    * do the temp1 + temp2 + carry addition correct.  carry is 64 bit because gcc has
136    * subtle issues when you mix 64 / 32 bit maths. */
137   uint64_t temp1, temp2, temp3;     /* temporary variables to help the SH-4, and gcc */
138   uint64_t carry;
139   int32_t index;
140
141   if (length1 == 0 || length2 == 0)
142     {
143       return 0;
144     }
145   else if (length1 < length2)
146     {
147       length2 = length1;
148     }
149
150   carry = 0;
151   index = 0;
152   do
153     {
154       temp1 = arg1[index];
155       temp2 = arg2[index];
156       temp3 = temp1 + temp2;
157       arg1[index] = temp3 + carry;
158       if (arg2[index] < arg1[index])
159         carry = 0;
160       else if (arg2[index] != arg1[index])
161         carry = 1;
162     }
163   while (++index < length2);
164   if (!carry)
165     return 0;
166   else if (index == length1)
167     return 1;
168
169   while (++arg1[index] == 0 && ++index < length1);
170
171   return index == length1;
172 }
173
174 void
175 subtractHighPrecision (uint64_t * arg1, int32_t length1, uint64_t * arg2, int32_t length2)
176 {
177   /* assumes arg1 > arg2 */
178   int32_t index;
179   for (index = 0; index < length1; ++index)
180     arg1[index] = ~arg1[index];
181   simpleAddHighPrecision (arg1, length1, 1);
182
183   while (length2 > 0 && arg2[length2 - 1] == 0)
184     --length2;
185
186   addHighPrecision (arg1, length1, arg2, length2);
187
188   for (index = 0; index < length1; ++index)
189     arg1[index] = ~arg1[index];
190   simpleAddHighPrecision (arg1, length1, 1);
191 }
192
193 static uint32_t simpleMultiplyHighPrecision(uint64_t* arg1, int32_t length, uint64_t arg2) {
194   /* assumes arg2 only holds 32 bits of information */
195   uint64_t product;
196   int32_t index;
197
198   index = 0;
199   product = 0;
200
201   do
202     {
203       product =
204         HIGH_IN_U64 (product) + arg2 * LOW_U32_FROM_PTR (arg1 + index);
205       LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (product);
206       product =
207         HIGH_IN_U64 (product) + arg2 * HIGH_U32_FROM_PTR (arg1 + index);
208       HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (product);
209     }
210   while (++index < length);
211
212   return HIGH_U32_FROM_VAR (product);
213 }
214
215 static void
216 simpleMultiplyAddHighPrecision (uint64_t * arg1, int32_t length, uint64_t arg2,
217                                 uint32_t * result)
218 {
219   /* Assumes result can hold the product and arg2 only holds 32 bits
220      of information */
221   uint64_t product;
222   int32_t index, resultIndex;
223
224   index = resultIndex = 0;
225   product = 0;
226
227   do
228     {
229       product =
230         HIGH_IN_U64 (product) + result[at (resultIndex)] +
231         arg2 * LOW_U32_FROM_PTR (arg1 + index);
232       result[at (resultIndex)] = LOW_U32_FROM_VAR (product);
233       ++resultIndex;
234       product =
235         HIGH_IN_U64 (product) + result[at (resultIndex)] +
236         arg2 * HIGH_U32_FROM_PTR (arg1 + index);
237       result[at (resultIndex)] = LOW_U32_FROM_VAR (product);
238       ++resultIndex;
239     }
240   while (++index < length);
241
242   result[at (resultIndex)] += HIGH_U32_FROM_VAR (product);
243   if (result[at (resultIndex)] < HIGH_U32_FROM_VAR (product))
244     {
245       /* must be careful with ++ operator and macro expansion */
246       ++resultIndex;
247       while (++result[at (resultIndex)] == 0)
248         ++resultIndex;
249     }
250 }
251
252 #if __BYTE_ORDER != __LITTLE_ENDIAN
253 void simpleMultiplyAddHighPrecisionBigEndianFix(uint64_t* arg1, int32_t length, uint64_t arg2, uint32_t* result) {
254         /* Assumes result can hold the product and arg2 only holds 32 bits
255            of information */
256         uint64_t product;
257         int32_t index, resultIndex;
258
259         index = resultIndex = 0;
260         product = 0;
261
262         do {
263                 product = HIGH_IN_U64(product) + result[halfAt(resultIndex)] + arg2 * LOW_U32_FROM_PTR(arg1 + index);
264                 result[halfAt(resultIndex)] = LOW_U32_FROM_VAR(product);
265                 ++resultIndex;
266                 product = HIGH_IN_U64(product) + result[halfAt(resultIndex)] + arg2 * HIGH_U32_FROM_PTR(arg1 + index);
267                 result[halfAt(resultIndex)] = LOW_U32_FROM_VAR(product);
268                 ++resultIndex;
269         } while (++index < length);
270
271         result[halfAt(resultIndex)] += HIGH_U32_FROM_VAR(product);
272         if (result[halfAt(resultIndex)] < HIGH_U32_FROM_VAR(product)) {
273                 /* must be careful with ++ operator and macro expansion */
274                 ++resultIndex;
275                 while (++result[halfAt(resultIndex)] == 0) ++resultIndex;
276         }
277 }
278 #endif
279
280 void
281 multiplyHighPrecision (uint64_t * arg1, int32_t length1, uint64_t * arg2, int32_t length2,
282                        uint64_t * result, int32_t length)
283 {
284   /* assumes result is large enough to hold product */
285   uint64_t* temp;
286   uint32_t* resultIn32;
287   int32_t count, index;
288
289   if (length1 < length2)
290     {
291       temp = arg1;
292       arg1 = arg2;
293       arg2 = temp;
294       count = length1;
295       length1 = length2;
296       length2 = count;
297     }
298
299   memset (result, 0, sizeof (uint64_t) * length);
300
301   /* length1 > length2 */
302   resultIn32 = reinterpret_cast<uint32_t*>(result);
303   index = -1;
304   for (count = 0; count < length2; ++count)
305     {
306       simpleMultiplyAddHighPrecision (arg1, length1, LOW_IN_U64 (arg2[count]),
307                                       resultIn32 + (++index));
308 #if __BYTE_ORDER == __LITTLE_ENDIAN
309       simpleMultiplyAddHighPrecision(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index));
310 #else
311       simpleMultiplyAddHighPrecisionBigEndianFix(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index));
312 #endif
313     }
314 }
315
316 uint32_t
317 simpleAppendDecimalDigitHighPrecision (uint64_t * arg1, int32_t length, uint64_t digit)
318 {
319   /* assumes digit is less than 32 bits */
320   uint64_t arg;
321   int32_t index = 0;
322
323   digit <<= 32;
324   do
325     {
326       arg = LOW_IN_U64 (arg1[index]);
327       digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg);
328       LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit);
329
330       arg = HIGH_IN_U64 (arg1[index]);
331       digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg);
332       HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit);
333     }
334   while (++index < length);
335
336   return HIGH_U32_FROM_VAR (digit);
337 }
338
339 void
340 simpleShiftLeftHighPrecision (uint64_t * arg1, int32_t length, int32_t arg2)
341 {
342   /* assumes length > 0 */
343   int32_t index, offset;
344   if (arg2 >= 64)
345     {
346       offset = arg2 >> 6;
347       index = length;
348
349       while (--index - offset >= 0)
350         arg1[index] = arg1[index - offset];
351       do
352         {
353           arg1[index] = 0;
354         }
355       while (--index >= 0);
356
357       arg2 &= 0x3F;
358     }
359
360   if (arg2 == 0)
361     return;
362   while (--length > 0)
363     {
364       arg1[length] = arg1[length] << arg2 | arg1[length - 1] >> (64 - arg2);
365     }
366   *arg1 <<= arg2;
367 }
368
369 int32_t
370 highestSetBit (uint64_t * y)
371 {
372   uint32_t x;
373   int32_t result;
374
375   if (*y == 0)
376     return 0;
377
378 #if defined(USE_LL)
379   if (*y & 0xFFFFFFFF00000000LL)
380     {
381       x = HIGH_U32_FROM_PTR (y);
382       result = 32;
383     }
384   else
385     {
386       x = LOW_U32_FROM_PTR (y);
387       result = 0;
388     }
389 #else
390 #if defined(USE_L)
391   if (*y & 0xFFFFFFFF00000000L)
392     {
393       x = HIGH_U32_FROM_PTR (y);
394       result = 32;
395     }
396   else
397     {
398       x = LOW_U32_FROM_PTR (y);
399       result = 0;
400     }
401 #else
402   if (*y & 0xFFFFFFFF00000000)
403     {
404       x = HIGH_U32_FROM_PTR (y);
405       result = 32;
406     }
407   else
408     {
409       x = LOW_U32_FROM_PTR (y);
410       result = 0;
411     }
412 #endif /* USE_L */
413 #endif /* USE_LL */
414
415   if (x & 0xFFFF0000)
416     {
417       x = bitSection (x, 0xFFFF0000, 16);
418       result += 16;
419     }
420   if (x & 0xFF00)
421     {
422       x = bitSection (x, 0xFF00, 8);
423       result += 8;
424     }
425   if (x & 0xF0)
426     {
427       x = bitSection (x, 0xF0, 4);
428       result += 4;
429     }
430   if (x > 0x7)
431     return result + 4;
432   else if (x > 0x3)
433     return result + 3;
434   else if (x > 0x1)
435     return result + 2;
436   else
437     return result + 1;
438 }
439
440 int32_t
441 lowestSetBit (uint64_t * y)
442 {
443   uint32_t x;
444   int32_t result;
445
446   if (*y == 0)
447     return 0;
448
449 #if defined(USE_LL)
450   if (*y & 0x00000000FFFFFFFFLL)
451     {
452       x = LOW_U32_FROM_PTR (y);
453       result = 0;
454     }
455   else
456     {
457       x = HIGH_U32_FROM_PTR (y);
458       result = 32;
459     }
460 #else
461 #if defined(USE_L)
462   if (*y & 0x00000000FFFFFFFFL)
463     {
464       x = LOW_U32_FROM_PTR (y);
465       result = 0;
466     }
467   else
468     {
469       x = HIGH_U32_FROM_PTR (y);
470       result = 32;
471     }
472 #else
473   if (*y & 0x00000000FFFFFFFF)
474     {
475       x = LOW_U32_FROM_PTR (y);
476       result = 0;
477     }
478   else
479     {
480       x = HIGH_U32_FROM_PTR (y);
481       result = 32;
482     }
483 #endif /* USE_L */
484 #endif /* USE_LL */
485
486   if (!(x & 0xFFFF))
487     {
488       x = bitSection (x, 0xFFFF0000, 16);
489       result += 16;
490     }
491   if (!(x & 0xFF))
492     {
493       x = bitSection (x, 0xFF00, 8);
494       result += 8;
495     }
496   if (!(x & 0xF))
497     {
498       x = bitSection (x, 0xF0, 4);
499       result += 4;
500     }
501
502   if (x & 0x1)
503     return result + 1;
504   else if (x & 0x2)
505     return result + 2;
506   else if (x & 0x4)
507     return result + 3;
508   else
509     return result + 4;
510 }
511
512 int32_t
513 highestSetBitHighPrecision (uint64_t * arg, int32_t length)
514 {
515   int32_t highBit;
516
517   while (--length >= 0)
518     {
519       highBit = highestSetBit (arg + length);
520       if (highBit)
521         return highBit + 64 * length;
522     }
523
524   return 0;
525 }
526
527 int32_t
528 lowestSetBitHighPrecision (uint64_t * arg, int32_t length)
529 {
530   int32_t lowBit, index = -1;
531
532   while (++index < length)
533     {
534       lowBit = lowestSetBit (arg + index);
535       if (lowBit)
536         return lowBit + 64 * index;
537     }
538
539   return 0;
540 }
541
542 int32_t
543 compareHighPrecision (uint64_t * arg1, int32_t length1, uint64_t * arg2, int32_t length2)
544 {
545   while (--length1 >= 0 && arg1[length1] == 0);
546   while (--length2 >= 0 && arg2[length2] == 0);
547
548   if (length1 > length2)
549     return 1;
550   else if (length1 < length2)
551     return -1;
552   else if (length1 > -1)
553     {
554       do
555         {
556           if (arg1[length1] > arg2[length1])
557             return 1;
558           else if (arg1[length1] < arg2[length1])
559             return -1;
560         }
561       while (--length1 >= 0);
562     }
563
564   return 0;
565 }
566
567 jdouble
568 toDoubleHighPrecision (uint64_t * arg, int32_t length)
569 {
570   int32_t highBit;
571   uint64_t mantissa, test64;
572   uint32_t test;
573   jdouble result;
574
575   while (length > 0 && arg[length - 1] == 0)
576     --length;
577
578   if (length == 0)
579     result = 0.0;
580   else if (length > 16)
581     {
582       DOUBLE_TO_LONGBITS (result) = EXPONENT_MASK;
583     }
584   else if (length == 1)
585     {
586       highBit = highestSetBit (arg);
587       if (highBit <= 53)
588         {
589           highBit = 53 - highBit;
590           mantissa = *arg << highBit;
591           DOUBLE_TO_LONGBITS (result) =
592             CREATE_DOUBLE_BITS (mantissa, -highBit);
593         }
594       else
595         {
596           highBit -= 53;
597           mantissa = *arg >> highBit;
598           DOUBLE_TO_LONGBITS (result) =
599             CREATE_DOUBLE_BITS (mantissa, highBit);
600
601           /* perform rounding, round to even in case of tie */
602           test = (LOW_U32_FROM_PTR (arg) << (11 - highBit)) & 0x7FF;
603           if (test > 0x400 || ((test == 0x400) && (mantissa & 1)))
604             DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1;
605         }
606     }
607   else
608     {
609       highBit = highestSetBit (arg + (--length));
610       if (highBit <= 53)
611         {
612           highBit = 53 - highBit;
613           if (highBit > 0)
614             {
615               mantissa =
616                 (arg[length] << highBit) | (arg[length - 1] >>
617                                             (64 - highBit));
618             }
619           else
620             {
621               mantissa = arg[length];
622             }
623           DOUBLE_TO_LONGBITS (result) =
624             CREATE_DOUBLE_BITS (mantissa, length * 64 - highBit);
625
626           /* perform rounding, round to even in case of tie */
627           test64 = arg[--length] << highBit;
628           if (test64 > SIGN_MASK || ((test64 == SIGN_MASK) && (mantissa & 1)))
629             DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1;
630           else if (test64 == SIGN_MASK)
631             {
632               while (--length >= 0)
633                 {
634                   if (arg[length] != 0)
635                     {
636                       DOUBLE_TO_LONGBITS (result) =
637                         DOUBLE_TO_LONGBITS (result) + 1;
638                       break;
639                     }
640                 }
641             }
642         }
643       else
644         {
645           highBit -= 53;
646           mantissa = arg[length] >> highBit;
647           DOUBLE_TO_LONGBITS (result) =
648             CREATE_DOUBLE_BITS (mantissa, length * 64 + highBit);
649
650           /* perform rounding, round to even in case of tie */
651           test = (LOW_U32_FROM_PTR (arg + length) << (11 - highBit)) & 0x7FF;
652           if (test > 0x400 || ((test == 0x400) && (mantissa & 1)))
653             DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1;
654           else if (test == 0x400)
655             {
656               do
657                 {
658                   if (arg[--length] != 0)
659                     {
660                       DOUBLE_TO_LONGBITS (result) =
661                         DOUBLE_TO_LONGBITS (result) + 1;
662                       break;
663                     }
664                 }
665               while (length > 0);
666             }
667         }
668     }
669
670   return result;
671 }
672
673 static uint64_t simpleMultiplyHighPrecision64(uint64_t* arg1, int32_t length, uint64_t arg2);
674
675 int32_t
676 timesTenToTheEHighPrecision (uint64_t * result, int32_t length, jint e)
677 {
678   /* assumes result can hold value */
679   uint64_t overflow;
680   int exp10 = e;
681
682   if (e == 0)
683     return length;
684
685   /* bad O(n) way of doing it, but simple */
686   /*
687      do {
688      overflow = simpleAppendDecimalDigitHighPrecision(result, length, 0);
689      if (overflow)
690      result[length++] = overflow;
691      } while (--e);
692    */
693   /* Replace the current implementaion which performs a
694    * "multiplication" by 10 e number of times with an actual
695    * multiplication. 10e19 is the largest exponent to the power of ten
696    * that will fit in a 64-bit integer, and 10e9 is the largest exponent to
697    * the power of ten that will fit in a 64-bit integer. Not sure where the
698    * break-even point is between an actual multiplication and a
699    * simpleAappendDecimalDigit() so just pick 10e3 as that point for
700    * now.
701    */
702   while (exp10 >= 19)
703     {
704       overflow = simpleMultiplyHighPrecision64 (result, length, TEN_E19);
705       if (overflow)
706         result[length++] = overflow;
707       exp10 -= 19;
708     }
709   while (exp10 >= 9)
710     {
711       overflow = simpleMultiplyHighPrecision (result, length, TEN_E9);
712       if (overflow)
713         result[length++] = overflow;
714       exp10 -= 9;
715     }
716   if (exp10 == 0)
717     return length;
718   else if (exp10 == 1)
719     {
720       overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0);
721       if (overflow)
722         result[length++] = overflow;
723     }
724   else if (exp10 == 2)
725     {
726       overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0);
727       if (overflow)
728         result[length++] = overflow;
729       overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0);
730       if (overflow)
731         result[length++] = overflow;
732     }
733   else if (exp10 == 3)
734     {
735       overflow = simpleMultiplyHighPrecision (result, length, TEN_E3);
736       if (overflow)
737         result[length++] = overflow;
738     }
739   else if (exp10 == 4)
740     {
741       overflow = simpleMultiplyHighPrecision (result, length, TEN_E4);
742       if (overflow)
743         result[length++] = overflow;
744     }
745   else if (exp10 == 5)
746     {
747       overflow = simpleMultiplyHighPrecision (result, length, TEN_E5);
748       if (overflow)
749         result[length++] = overflow;
750     }
751   else if (exp10 == 6)
752     {
753       overflow = simpleMultiplyHighPrecision (result, length, TEN_E6);
754       if (overflow)
755         result[length++] = overflow;
756     }
757   else if (exp10 == 7)
758     {
759       overflow = simpleMultiplyHighPrecision (result, length, TEN_E7);
760       if (overflow)
761         result[length++] = overflow;
762     }
763   else if (exp10 == 8)
764     {
765       overflow = simpleMultiplyHighPrecision (result, length, TEN_E8);
766       if (overflow)
767         result[length++] = overflow;
768     }
769   return length;
770 }
771
772 uint64_t
773 doubleMantissa (jdouble z)
774 {
775   uint64_t m = DOUBLE_TO_LONGBITS (z);
776
777   if ((m & EXPONENT_MASK) != 0)
778     m = (m & MANTISSA_MASK) | NORMAL_MASK;
779   else
780     m = (m & MANTISSA_MASK);
781
782   return m;
783 }
784
785 int32_t
786 doubleExponent (jdouble z)
787 {
788   /* assumes positive double */
789   int32_t k = HIGH_U32_FROM_VAR (z) >> 20;
790
791   if (k)
792     k -= E_OFFSET;
793   else
794     k = 1 - E_OFFSET;
795
796   return k;
797 }
798
799 uint32_t floatMantissa(jfloat z) {
800   uint32_t m = FLOAT_TO_INTBITS (z);
801
802   if ((m & FLOAT_EXPONENT_MASK) != 0)
803     m = (m & FLOAT_MANTISSA_MASK) | FLOAT_NORMAL_MASK;
804   else
805     m = (m & FLOAT_MANTISSA_MASK);
806
807   return m;
808 }
809
810 int32_t
811 floatExponent (jfloat z)
812 {
813   /* assumes positive float */
814   int32_t k = FLOAT_TO_INTBITS (z) >> 23;
815   if (k)
816     k -= FLOAT_E_OFFSET;
817   else
818     k = 1 - FLOAT_E_OFFSET;
819
820   return k;
821 }
822
823 /* Allow a 64-bit value in arg2 */
824 uint64_t
825 simpleMultiplyHighPrecision64 (uint64_t * arg1, int32_t length, uint64_t arg2)
826 {
827   uint64_t intermediate, carry1, carry2, prod1, prod2, sum;
828   uint64_t* pArg1;
829   int32_t index;
830   uint32_t buf32;
831
832   index = 0;
833   intermediate = 0;
834   pArg1 = arg1 + index;
835   carry1 = carry2 = 0;
836
837   do
838     {
839       if ((*pArg1 != 0) || (intermediate != 0))
840         {
841           prod1 =
842             static_cast<uint64_t>(LOW_U32_FROM_VAR (arg2)) * static_cast<uint64_t>(LOW_U32_FROM_PTR (pArg1));
843           sum = intermediate + prod1;
844           if ((sum < prod1) || (sum < intermediate))
845             {
846               carry1 = 1;
847             }
848           else
849             {
850               carry1 = 0;
851             }
852           prod1 =
853             static_cast<uint64_t>(LOW_U32_FROM_VAR (arg2)) * static_cast<uint64_t>(HIGH_U32_FROM_PTR (pArg1));
854           prod2 =
855             static_cast<uint64_t>(HIGH_U32_FROM_VAR (arg2)) * static_cast<uint64_t>(LOW_U32_FROM_PTR (pArg1));
856           intermediate = carry2 + HIGH_IN_U64 (sum) + prod1 + prod2;
857           if ((intermediate < prod1) || (intermediate < prod2))
858             {
859               carry2 = 1;
860             }
861           else
862             {
863               carry2 = 0;
864             }
865           LOW_U32_FROM_PTR (pArg1) = LOW_U32_FROM_VAR (sum);
866           buf32 = HIGH_U32_FROM_PTR (pArg1);
867           HIGH_U32_FROM_PTR (pArg1) = LOW_U32_FROM_VAR (intermediate);
868           intermediate = carry1 + HIGH_IN_U64 (intermediate)
869             + static_cast<uint64_t>(HIGH_U32_FROM_VAR (arg2)) * static_cast<uint64_t>(buf32);
870         }
871       pArg1++;
872     }
873   while (++index < length);
874   return intermediate;
875 }