Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 57424 invoked from network); 1 Dec 2005 06:22:36 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 1 Dec 2005 06:22:36 -0000 Received: (qmail 10404 invoked by uid 500); 1 Dec 2005 06:17:50 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 7788 invoked by uid 500); 1 Dec 2005 06:17:29 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 1737 invoked by uid 99); 1 Dec 2005 06:16:21 -0000 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Wed, 30 Nov 2005 22:12:47 -0800 Received: (qmail 44085 invoked by uid 65534); 1 Dec 2005 06:11:39 -0000 Message-ID: <20051201061139.44084.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r350181 [153/198] - in /incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core: ./ depends/ depends/files/ depends/jars/ depends/libs/ depends/libs/linux.IA32/ depends/libs/win.IA32/ depends/oss/ depends/oss/linux.IA32/ depends/oss/win.... Date: Thu, 01 Dec 2005 06:04:00 -0000 To: harmony-commits@incubator.apache.org From: geirm@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/bigint.c URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/bigint.c?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/bigint.c (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/bigint.c Wed Nov 30 21:29:27 2005 @@ -0,0 +1,1280 @@ +/* Copyright 1991, 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "jcl.h" + +/* macros for Endian portability + at() mangles array indices to count 1,0,3,2,5,4,... on BigEndian platforms + atx() mangles array indices to count 1,0,3,2,5,4,... on BigEndian platforms, except 64 bit platforms + where counting slots must still go in numerical order + copysize() mangles array sizes to copy so on BigEndian platforms, 5 becomes 6 because + the 5th word in memory is skipped and the 5th word of the number is stored in the 6th memory word +*/ + +#define at(i) (i) +#define copysize(i) (i) + +#define U64_ADD(addr1, addr2) (*(U_64*)(addr1) += *(U_64*)(addr2)) +#define U64_GREATER(addr1, addr2) (*(U_64*)(addr1) > *(U_64*)(addr2)) +#define U64_SUBTRACT_LONG(addr1, u32) (*(U_64*)(addr1) -= (U_64)(u32)) +#define LONG_MULT(i1,i2,res) (*(U_64*)res = (U_64)i1 * (U_64)i2) +#define LONG_DIV(u64, div) ((U_32)(*(U_64*)(u64) / (U_32)(div))) +#define LONG_REM(u64, div) ((U_32)(*(U_64*)(u64) % (U_32)(div))) + + /* 32 bit */ +#define IS_NEGATIVE(ar,len) (((I_32*)ar)[at(len*2-1)] < 0) +#define atx(i) (at(i)) + +#define GET_LENGTH(obj) ((*env)->GetArrayLength(env,obj)) +#define GET_ELEMENTS(obj) ((U_32*)(*env)->GetLongArrayElements(env, obj, NULL)) +#define RELEASE_ELEMENTS(obj,ar,save) ((*env)->ReleaseLongArrayElements(env, obj, (jlong*)ar, save ? 0 : JNI_ABORT)) +#define GET_ELEMENTS_CRITICAL(obj) ((U_32*)(*env)->GetPrimitiveArrayCritical(env, obj, NULL)) +#define RELEASE_ELEMENTS_CRITICAL(obj,ar,save) ((*env)->ReleasePrimitiveArrayCritical(env, obj, (jlong*)ar, save ? 0 : JNI_ABORT)) +#define NEW_OBJECT(length) ((*env)->NewLongArray(env,length)) + +jlongArray internalBigIntegerNormalize +PROTOTYPE ((JNIEnv * env, jlongArray src1)); +jlongArray internalBigIntegerAdd +PROTOTYPE ((JNIEnv * env, jlongArray src1, jlongArray src2)); +static void RIGHT_SHIFT PROTOTYPE ((void *arIn, IDATA lenIn, IDATA shiftval)); +jlongArray internalBigIntegerNeg PROTOTYPE ((JNIEnv * env, jlongArray src1)); +static U_32 internalIntegerSubtractWithCarry +PROTOTYPE ((U_32 a1, U_32 a2, U_32 * carry)); +jlongArray grow PROTOTYPE ((JNIEnv * env, jlongArray src1, jlong element)); +static void LEFT_SHIFT PROTOTYPE ((void *arIn, IDATA lenIn, IDATA shiftval)); +static U_32 internalIntegerAddWithCarry +PROTOTYPE ((U_32 a1, U_32 a2, U_32 * carry)); + +static void +LEFT_SHIFT (void *arIn, IDATA lenIn, IDATA shiftval) +{ + IDATA oldAt, newAt, shiftvalr, i, len = (lenIn + 1) / 2; + U_64 *ar = (U_64 *) arIn; + + oldAt = 0, newAt = shiftval / 64; + shiftval = shiftval % 64; + shiftvalr = 64 - shiftval; + + if (shiftval == 0) + { + /* straight copy */ + for (i = len - 1; i >= newAt; i--) + ar[i] = ar[i - newAt]; + } + else + { + for (i = len - 1; i > newAt; i--) + ar[i] = + (ar[i - newAt] << shiftval) | (ar[i - newAt - 1] >> shiftvalr); + /* zero extend low word */ + ar[newAt] = (ar[0] << shiftval); + } + for (i = 0; i < newAt; i++) + ar[newAt] = 0; +} +static void +RIGHT_SHIFT (void *arIn, IDATA lenIn, IDATA shiftval) +{ + IDATA oldAt, newAt, shiftvalr, len = (lenIn + 1) / 2; + U_64 *ar = (U_64 *) arIn; + + oldAt = shiftval / 64, newAt = 0; + shiftval = shiftval % 64; + shiftvalr = 64 - shiftval; + + if (shiftval == 0) + { + /* straight copy */ + for (; oldAt < len; oldAt++, newAt++) + ar[newAt] = ar[oldAt]; + } + else + { + for (; oldAt < len - 1; oldAt++, newAt++) + ar[newAt] = (ar[oldAt] >> shiftval) | (ar[oldAt + 1] << shiftvalr); + /* sign extend high word */ + ar[newAt++] = (((I_64) ar[oldAt]) >> shiftval); + } + for (; newAt < len; newAt++) + ar[newAt] = 0; +} + +jlongArray JNICALL +Java_com_ibm_oti_util_math_BigInteger_addImpl (JNIEnv * env, jclass cls, + jlongArray src1, + jlongArray src2) +{ + return internalBigIntegerAdd (env, src1, src2); +} + +jint JNICALL +Java_com_ibm_oti_util_math_BigInteger_compImpl (JNIEnv * env, jclass cls, + jlongArray src1, + jlongArray src2) +{ + /* return -1, 0, 1 if src1 is less than, equal to, or greater than src2 */ + IDATA len1, len2; + UDATA *ar1, *ar2; + jint result = 0; + IDATA neg1 = 0, neg2 = 0, i; + + len1 = GET_LENGTH (src1); + len2 = GET_LENGTH (src2); + + if (!(ar1 = (UDATA *) GET_ELEMENTS_CRITICAL (src1))) + goto done; + if (!(ar2 = (UDATA *) GET_ELEMENTS_CRITICAL (src2))) + goto release1; + + neg1 = IS_NEGATIVE (ar1, len1); + neg2 = IS_NEGATIVE (ar2, len2); + + len1 *= 2; + len2 *= 2; + + if (neg1 != neg2) /* different signs */ + result = neg2 ? 1 : -1; + else + { + if (len1 != len2) + { + if (neg1 == 0) /* positive/zero case */ + result = len1 > len2 ? 1 : -1; + else /* negative case */ + result = len1 > len2 ? -1 : 1; + goto release2; + } + else + { /* len1==len2 */ + if (ar1[atx (len1 - 1)] != ar2[atx (len1 - 1)]) + { + result = + ((IDATA *) ar1)[atx (len1 - 1)] > + ((IDATA *) ar2)[atx (len1 - 1)] ? 1 : -1; + goto release2; + } + for (i = len1 - 2; i >= 0; i--) + if (ar1[atx (i)] != ar2[atx (i)]) + { + result = ar1[atx (i)] > ar2[atx (i)] ? 1 : -1; + goto release2; + } + } + } +release2: + RELEASE_ELEMENTS_CRITICAL (src2, ar2, 0); +release1: + RELEASE_ELEMENTS_CRITICAL (src1, ar1, 0); +done: + return result; +} + +jlongArray JNICALL +Java_com_ibm_oti_util_math_BigInteger_divImpl (JNIEnv * env, jclass cls, + jlongArray topObject, + jlongArray bottomObject) +{ + /* ASSUME that bottomObject is nonzero, ie check and throw was done in java */ + IDATA topLength, bottomLength, topSize, bottomSize, resultLength, + resultSize; + jlongArray resultObject; + U_32 *topStart = NULL, *bottomStart = NULL, *resultStart = NULL; + IDATA topAt, bottomAt, resultAt; + IDATA isNegative = 0; + I_32 signedTemp; + IDATA shift, tempNeg; + + U_32 j; + IDATA fromPtr; + IDATA fromPtr2; + IDATA multPtr; + U_32 v1; + U_32 v2; + IDATA highDigit; + + topLength = GET_LENGTH (topObject); + bottomLength = GET_LENGTH (bottomObject); + + /* make both integers positive, store if the result will be positive or negative */ + if (!(topStart = GET_ELEMENTS_CRITICAL (topObject))) + goto error; + tempNeg = IS_NEGATIVE (topStart, topLength); + RELEASE_ELEMENTS_CRITICAL (topObject, topStart, 0); + topStart = NULL; + if (tempNeg) + { + isNegative ^= 1; + if (!(topObject = internalBigIntegerNeg (env, topObject))) + goto error; + topLength = GET_LENGTH (topObject); + } + + if (!(bottomStart = GET_ELEMENTS_CRITICAL (bottomObject))) + goto error; + tempNeg = IS_NEGATIVE (bottomStart, bottomLength); + RELEASE_ELEMENTS_CRITICAL (bottomObject, bottomStart, 0); + bottomStart = NULL; + if (tempNeg) + { + isNegative ^= 1; + if (!(bottomObject = internalBigIntegerNeg (env, bottomObject))) + goto error; + bottomLength = GET_LENGTH (bottomObject); + } + + if (!(topStart = GET_ELEMENTS (topObject))) + goto error; + if (!(bottomStart = GET_ELEMENTS (bottomObject))) + goto error; + + /* Get the magnitude of the bottom integer */ + bottomSize = bottomLength * 2; + while (!bottomStart[at (bottomSize - 1)]) + bottomSize--; + + /* Get the magnitude of the top integer, will need a 0 on the end */ + topSize = topLength * 2; + while (topSize > 1 && !topStart[at (topSize - 1)] + && !topStart[at (topSize - 2)]) + topSize--; + + /* easy case if the bottom is a U32 */ + if (bottomSize == 1) + { + U_64 temp; + U_32 divisor = bottomStart[at (0)]; + + if (topSize > 1 && !topStart[at (topSize - 1)]) + topSize--; + + /* Add extra int on the end for sign */ + resultSize = topSize + 1; + resultLength = (resultSize + 1) / 2; + if (!(resultObject = NEW_OBJECT (resultLength))) + goto error; + if (!(resultStart = GET_ELEMENTS (resultObject))) + goto error; + + topAt = topSize - 1; + resultAt = resultSize - 2; + HIGH_LONG (temp) = 0; + do + { + LOW_LONG (temp) = topStart[at (topAt--)]; + resultStart[at (resultAt--)] = LONG_DIV (&temp, divisor); + HIGH_LONG (temp) = LONG_REM (&temp, divisor); + } + while (!(--topSize == 0)); + + goto finished; + } + + /* ensure top starts with a zero int */ + if (topStart[at (topSize - 1)] != 0) + { + if (topSize >= topLength * 2) + { /* allocate extra space */ + IDATA i; + U_32 *tempPtr; + jlongArray tempObject; + if (!(tempObject = NEW_OBJECT (topLength + 1))) + goto error; /* initialized to zero */ + if (!(tempPtr = GET_ELEMENTS (tempObject))) + goto error; + for (i = 0; i < copysize (topSize); i++) + tempPtr[i] = topStart[i]; + RELEASE_ELEMENTS (topObject, topStart, 0); + topObject = tempObject; + topStart = tempPtr; + topLength++; + } + topSize++; + } + + /* If the bottom int has a larger size than the top int, the result + * is 0. Subtract one from the topSize before the comparison to account + * for the 0 added to the end. */ + + if (bottomSize > (topSize - 1)) + { + /* release objects */ + RELEASE_ELEMENTS (topObject, topStart, 0); + topStart = NULL; + RELEASE_ELEMENTS (bottomObject, bottomStart, 0); + bottomStart = NULL; + if (!(resultObject = NEW_OBJECT (1))) + goto error; /* initialized to zero */ + return resultObject; + } + + /* Shift the bottom int until its high bit is set */ + + highDigit = bottomSize - 1; + signedTemp = (I_32) bottomStart[at (highDigit)]; + shift = 0; + while (signedTemp >= 0) + ++shift, signedTemp <<= 1; + LEFT_SHIFT (bottomStart, bottomSize, shift); + LEFT_SHIFT (topStart, topSize, shift); + v1 = bottomStart[at (highDigit)]; + v2 = bottomStart[at (highDigit - 1)]; + j = topSize - bottomSize; + + /* Create the result object. It must have an extra long added for sign */ + resultSize = j + 1; + resultLength = (resultSize + 1) / 2; + if (!(resultObject = NEW_OBJECT (resultLength))) + goto error; + if (!(resultStart = GET_ELEMENTS (resultObject))) + goto error; + + /* Initialize */ + bottomAt = 0; + topAt = 0; + fromPtr = topAt + topSize - 1; + fromPtr2 = fromPtr - 1; + resultAt = j; + multPtr = topAt + j; + + /* Calculate the digits of the result */ + do + { + U_64 t1; + U_64 t2; + U_32 qHat; + IDATA from; + IDATA to; + U_32 size; + U_32 carry; + + /* Calculate qHat */ + + if ((HIGH_LONG (t1) = topStart[at (fromPtr--)]) == v1) + { + qHat = 0xFFFFFFFF; + --fromPtr2; + } + else + { + LOW_LONG (t1) = topStart[at (fromPtr)]; + qHat = LONG_DIV (&t1, v1); + HIGH_LONG (t2) = LONG_REM (&t1, v1); + LOW_LONG (t2) = topStart[at (--fromPtr2)]; + LONG_MULT (qHat, v2, &t1); + while (U64_GREATER (&t1, &t2)) + { + --qHat; + carry = 0; + HIGH_LONG (t2) = + internalIntegerAddWithCarry (HIGH_LONG (t2), v1, &carry); + /* Stop if t2 grows larger than a U_64 */ + if (carry) + { + break; + } + U64_SUBTRACT_LONG (&t1, v2); + } + } + resultStart[at (--resultAt)] = qHat; + + /* Subtract factored part */ + + from = bottomAt; + to = --multPtr; + size = bottomSize; + LOW_LONG (t1) = 0; + carry = 0; + do + { + HIGH_LONG (t1) = 0; + LONG_MULT (bottomStart[at (from++)], qHat, &t2); + U64_ADD (&t1, &t2); + topStart[at (to)] = + internalIntegerSubtractWithCarry (topStart[at (to)], + LOW_LONG (t1), &carry); + to++; + LOW_LONG (t1) = HIGH_LONG (t1); + } + while (!(--size == 0)); + topStart[at (to)] = + internalIntegerSubtractWithCarry (topStart[at (to)], LOW_LONG (t1), + &carry); + + /* Check for add back */ + + if (carry) + { + --resultStart[at (resultAt)]; + carry = 0; + from = bottomAt; + to = multPtr; + size = bottomSize; + do + { + topStart[at (to)] = + internalIntegerAddWithCarry (topStart[at (to)], + bottomStart[at (from++)], + &carry); + to++; + } + while (!(--size == 0)); + topStart[at (to)] = 0; + } + } + while (!(--j == 0)); + +finished: + /* release objects */ + RELEASE_ELEMENTS (topObject, topStart, 0); + RELEASE_ELEMENTS (bottomObject, bottomStart, 0); + RELEASE_ELEMENTS (resultObject, resultStart, 1); + + /* ensure result is normalized */ + if (!(resultObject = internalBigIntegerNormalize (env, resultObject))) + return NULL; + /* negate the result if inputs had opposite signs */ + if (isNegative) + if (!(resultObject = internalBigIntegerNeg (env, resultObject))) + return NULL; + return resultObject; + +error: + if (topStart) + RELEASE_ELEMENTS (topObject, topStart, 0); + if (bottomStart) + RELEASE_ELEMENTS (bottomObject, bottomStart, 0); + if (resultStart) + RELEASE_ELEMENTS (resultObject, resultStart, 0); + return NULL; +} + +jlongArray JNICALL +Java_com_ibm_oti_util_math_BigInteger_mulImpl (JNIEnv * env, jclass cls, + jlongArray src1, + jlongArray src2) +{ + IDATA len1, len2, lenR; + jlongArray resultObject; + U_32 *ar1 = NULL, *ar2 = NULL, *arR = NULL; + IDATA isNegative = 0, tempNeg; + IDATA shortAt, resultAt; + + IDATA shortSize, longSize; + U_32 *longer, *shorter, *result; + + len1 = GET_LENGTH (src1); + len2 = GET_LENGTH (src2); + + /* make both integers positive, store if the result will be positive or negative */ + if (!(ar1 = GET_ELEMENTS_CRITICAL (src1))) + goto error; + tempNeg = IS_NEGATIVE (ar1, len1); + RELEASE_ELEMENTS_CRITICAL (src1, ar1, 0); + ar1 = NULL; + if (tempNeg) + { + isNegative ^= 1; + if (!(src1 = internalBigIntegerNeg (env, src1))) + goto error; + len1 = GET_LENGTH (src1); + } + + if (!(ar2 = GET_ELEMENTS_CRITICAL (src2))) + goto error; + tempNeg = IS_NEGATIVE (ar2, len2); + RELEASE_ELEMENTS_CRITICAL (src2, ar2, 0); + ar2 = NULL; + if (tempNeg) + { + isNegative ^= 1; + if (!(src2 = internalBigIntegerNeg (env, src2))) + goto error; + len2 = GET_LENGTH (src2); + } + if (!(ar1 = GET_ELEMENTS (src1))) + goto error; + if (!(ar2 = GET_ELEMENTS (src2))) + goto error; + + /* make ar1 the longer integer */ + if (len2 > len1) + { + void *temp; + IDATA tempint; + temp = src1; + src1 = src2; + src2 = temp; + temp = ar1; + ar1 = ar2; + ar2 = temp; + tempint = len1; + len1 = len2; + len2 = tempint; + } + + /* allocate new long of length len1+len2 */ + lenR = len1 + len2; + if (!(resultObject = NEW_OBJECT (lenR))) + goto error; + if (!(arR = GET_ELEMENTS (resultObject))) + goto error; + + /* Perform long multiplication with the second integer "on the bottom" */ + shorter = ar2; + shortAt = 0; + longer = ar1; + shortSize = len2 * 2; + longSize = len1 * 2; + result = arR; + resultAt = 0; + do + { + U_32 fromShort = shorter[at (shortAt++)]; + IDATA longAt = 0; + IDATA toAt = resultAt++; + U_32 size = longSize; + U_32 addCarry = 0; + U_32 multCarry = 0; + U_64 mult; + U_32 carry; + + do + { + LONG_MULT (fromShort, longer[at (longAt++)], &mult); + carry = 0; + LOW_LONG (mult) = + internalIntegerAddWithCarry (LOW_LONG (mult), multCarry, &carry); + HIGH_LONG (mult) = + internalIntegerAddWithCarry (HIGH_LONG (mult), 0, &carry); + multCarry = HIGH_LONG (mult); + carry = addCarry; + result[at (toAt)] = + internalIntegerAddWithCarry (result[at (toAt)], LOW_LONG (mult), + &carry); + toAt++; + addCarry = carry; + } + while (!(--size == 0)); + result[at (toAt++)] = multCarry + addCarry; + } + while (!(--shortSize == 0)); + + RELEASE_ELEMENTS (src1, ar1, 0); + RELEASE_ELEMENTS (src2, ar2, 0); + RELEASE_ELEMENTS (resultObject, arR, 1); + + /* ensure result is normalized */ + if (!(resultObject = internalBigIntegerNormalize (env, resultObject))) + return NULL; + /* negate the result if inputs had opposite signs */ + if (isNegative) + if (!(resultObject = internalBigIntegerNeg (env, resultObject))) + return NULL; + return resultObject; + +error: + if (ar1) + RELEASE_ELEMENTS (src1, ar1, 0); + if (ar2) + RELEASE_ELEMENTS (src2, ar2, 0); + if (arR) + RELEASE_ELEMENTS (resultObject, arR, 0); + return NULL; +} + +jlongArray JNICALL +Java_com_ibm_oti_util_math_BigInteger_negImpl (JNIEnv * env, jclass cls, + jlongArray src) +{ + return internalBigIntegerNeg (env, src); +} + +jlongArray JNICALL +Java_com_ibm_oti_util_math_BigInteger_remImpl (JNIEnv * env, jclass cls, + jlongArray topObject, + jlongArray bottomObject) +{ + /* ASSUME that bottomObject is nonzero, ie check and throw was done in java */ + IDATA topLength, bottomLength, topSize, bottomSize, resultLength, + resultSize; + jlongArray resultObject; + U_32 *topStart = NULL, *bottomStart = NULL, *resultStart = NULL; + IDATA topAt, bottomAt, resultAt, i, topZeroAdded = 0, tempNeg; + I_32 signedTemp; + + BOOLEAN firstNegative = 0; + U_32 j; + IDATA fromPtr, fromPtr2, multPtr; + U_32 v1; + U_32 v2; + UDATA shift; + IDATA highDigit; + + topLength = GET_LENGTH (topObject); + bottomLength = GET_LENGTH (bottomObject); + + /* make both integers positive, store if the result will be positive or negative */ + if (!(topStart = GET_ELEMENTS_CRITICAL (topObject))) + goto error; + tempNeg = IS_NEGATIVE (topStart, topLength); + RELEASE_ELEMENTS_CRITICAL (topObject, topStart, 0); + topStart = NULL; + if (tempNeg) + { + firstNegative = 1; + if (!(topObject = internalBigIntegerNeg (env, topObject))) + goto error; + topLength = GET_LENGTH (topObject); + } + + if (!(bottomStart = GET_ELEMENTS_CRITICAL (bottomObject))) + goto error; + tempNeg = IS_NEGATIVE (bottomStart, bottomLength); + RELEASE_ELEMENTS_CRITICAL (bottomObject, bottomStart, 0); + bottomStart = NULL; + if (tempNeg) + { + if (!(bottomObject = internalBigIntegerNeg (env, bottomObject))) + goto error; + bottomLength = GET_LENGTH (bottomObject); + } + + if (!(topStart = GET_ELEMENTS (topObject))) + goto error; + if (!(bottomStart = GET_ELEMENTS (bottomObject))) + goto error; + + /* Get the magnitude of the bottom integer */ + bottomSize = bottomLength * 2; + while (!bottomStart[at (bottomSize - 1)]) + bottomSize--; + + /* Get the magnitude of the top integer, will need a 0 on the end */ + topSize = topLength * 2; + while (topSize > 1 && !topStart[at (topSize - 1)] + && !topStart[at (topSize - 2)]) + topSize--; + + /* easy case of divide by a U32 - answer is a U32 */ + if (bottomSize == 1) + { + U_64 temp; + U_32 divisor = bottomStart[at (0)]; + + if (topSize > 1 && !topStart[at (topSize - 1)]) + topSize--; + + resultLength = resultSize = 1; + if (!(resultObject = NEW_OBJECT (resultLength))) + goto error; + if (!(resultStart = GET_ELEMENTS (resultObject))) + goto error; + + topAt = topSize - 1; + + HIGH_LONG (temp) = 0; + do + { + LOW_LONG (temp) = topStart[at (topAt--)]; + HIGH_LONG (temp) = LONG_REM (&temp, divisor); + } + while (!(--topSize == 0)); + + resultStart[at (0)] = HIGH_LONG (temp); + + RELEASE_ELEMENTS (topObject, topStart, 0); + goto finished; + } + + /* ensure top starts with a zero int */ + if (topStart[at (topSize - 1)] != 0) + { + if (topSize >= topLength * 2) + { /* allocate extra space */ + IDATA i; + U_32 *tempPtr; + jlongArray tempObject; + if (!(tempObject = NEW_OBJECT (topLength + 1))) + goto error; /* initialized to zero */ + if (!(tempPtr = GET_ELEMENTS (tempObject))) + goto error; + for (i = 0; i < copysize (topSize); i++) + tempPtr[i] = topStart[i]; + RELEASE_ELEMENTS (topObject, topStart, 0); + topObject = tempObject; + topStart = tempPtr; + topLength++; + topZeroAdded = 1; + } + topSize++; + } + + /* If the bottom int is larger than the top int, the result is the top + int. Subtract one from the topSize before comparison to account for + the 0 added to the end. + */ + if (bottomSize > (topSize - 1)) + { + /* clean up and ensure we are returning a new long[] with the same value as that passed in */ + RELEASE_ELEMENTS (bottomObject, bottomStart, 0); + bottomStart = NULL; + + if (!topZeroAdded) + { + if (firstNegative) + { + /* un-negate to get a copy */ + RELEASE_ELEMENTS (topObject, topStart, 0); + topStart = NULL; + if (!(resultObject = internalBigIntegerNeg (env, topObject))) + goto error; + } + else + { + /* we still have the original top, so must copy before returning because + we don't want to return the passed in object */ + if (!(resultObject = NEW_OBJECT (topLength))) + goto error; + if (!(resultStart = GET_ELEMENTS (resultObject))) + goto error; + for (i = 0; i < copysize (topSize); i++) + resultStart[i] = topStart[i]; + RELEASE_ELEMENTS (topObject, topStart, 0); + RELEASE_ELEMENTS (resultObject, resultStart, 1); + } + } + else if (topZeroAdded) + { + /* else topObject is already a copy, normalize it and return */ + RELEASE_ELEMENTS (topObject, topStart, 1); + topStart = NULL; + if (!(resultObject = internalBigIntegerNormalize (env, topObject))) + goto error; + if (firstNegative) + if (!(resultObject = internalBigIntegerNeg (env, resultObject))) + goto error; + } + return resultObject; + } + + /* Shift the bottom int until its high bit is set */ + + highDigit = bottomSize - 1; + shift = 0; + signedTemp = (I_32) bottomStart[at (highDigit)]; + while (signedTemp >= 0) + ++shift, signedTemp <<= 1; + LEFT_SHIFT (bottomStart, bottomSize, shift); + LEFT_SHIFT (topStart, topSize, shift); + v1 = bottomStart[at (highDigit)]; + v2 = bottomStart[at (highDigit - 1)]; + j = topSize - bottomSize; + + /* Initialize */ + +/* algorithm wants to make the result a modified (in place) top, + * so allocate new result and copy top into it, point top at the result */ + resultLength = topLength; + if (!(resultObject = NEW_OBJECT (resultLength))) + goto error; + if (!(resultStart = GET_ELEMENTS (resultObject))) + goto error; + resultSize = topSize; + for (i = 0; i < resultLength * 2; i++) + resultStart[i] = topStart[i]; + + /* release top object now, then point at result object */ + RELEASE_ELEMENTS (topObject, topStart, 0); + topStart = resultStart; + topAt = 0; + + resultAt = resultSize; + bottomAt = 0; + fromPtr = topAt + topSize - 1; + fromPtr2 = fromPtr - 1; + multPtr = topAt + j; + + /* Calculate the digits of the result */ + + do + { + U_64 t1; + U_64 t2; + U_32 qHat; + IDATA from, to; + U_32 size; + U_32 carry; + + /* Calculate qHat */ + + if ((HIGH_LONG (t1) = topStart[at (fromPtr--)]) == v1) + { + qHat = 0xFFFFFFFF; + --fromPtr2; + } + else + { + LOW_LONG (t1) = topStart[at (fromPtr)]; + qHat = LONG_DIV (&t1, v1); + HIGH_LONG (t2) = LONG_REM (&t1, v1); + LOW_LONG (t2) = topStart[at (--fromPtr2)]; + LONG_MULT (qHat, v2, &t1); + while (U64_GREATER (&t1, &t2)) + { + --qHat; + carry = 0; + HIGH_LONG (t2) = + internalIntegerAddWithCarry (HIGH_LONG (t2), v1, &carry); + /* Stop if t2 grows larger than a U_64 */ + if (carry) + { + break; + } + U64_SUBTRACT_LONG (&t1, v2); + } + } + + /* Subtract factored part */ + + from = bottomAt; + to = --multPtr; + size = bottomSize; + LOW_LONG (t1) = 0; + carry = 0; + do + { + HIGH_LONG (t1) = 0; + LONG_MULT (bottomStart[at (from++)], qHat, &t2); + U64_ADD (&t1, &t2); + topStart[at (to)] = + internalIntegerSubtractWithCarry (topStart[at (to)], + LOW_LONG (t1), &carry); + to++; + LOW_LONG (t1) = HIGH_LONG (t1); + } + while (!(--size == 0)); + topStart[at (to)] = + internalIntegerSubtractWithCarry (topStart[at (to)], LOW_LONG (t1), + &carry); + + /* Check for add back */ + + if (carry) + { + carry = 0; + from = bottomAt; + to = multPtr; + size = bottomSize; + do + { + topStart[at (to)] = + internalIntegerAddWithCarry (topStart[at (to)], + bottomStart[at (from++)], + &carry); + to++; + } + while (!(--size == 0)); + topStart[at (to)] = 0; + } + } + while (!(--j == 0)); + + /* Shift the result int back */ + RIGHT_SHIFT (resultStart, resultSize, shift); + +finished: + /* release objects */ + RELEASE_ELEMENTS (bottomObject, bottomStart, 0); + RELEASE_ELEMENTS (resultObject, resultStart, 1); + + /* ensure result is normalized */ + if (!(resultObject = internalBigIntegerNormalize (env, resultObject))) + return NULL; + /* If top integer was negative, the result must be negated. */ + if (firstNegative) + if (!(resultObject = internalBigIntegerNeg (env, resultObject))) + return NULL; + return resultObject; + +error: + if (topStart) + RELEASE_ELEMENTS (topObject, topStart, 0); + if (bottomStart) + RELEASE_ELEMENTS (bottomObject, bottomStart, 0); + if (resultStart) + RELEASE_ELEMENTS (resultObject, resultStart, 0); + return NULL; + +} + +jlongArray JNICALL +Java_com_ibm_oti_util_math_BigInteger_shlImpl (JNIEnv * env, jclass cls, + jlongArray src, jint shiftval) +{ + IDATA len, lenR; + jlongArray resultObject; + U_64 *ar = NULL, *shifted = NULL; + IDATA oldAt, newAt, shiftvalr, shortenedFlag = 0; + + len = GET_LENGTH (src); + + if (shiftval > 0) + { /* shift left */ + oldAt = 0, newAt = shiftval / 64; + shiftval = shiftval % 64; + shiftvalr = 64 - shiftval; + lenR = len + newAt + 1; + + /* attemp to pre-normalize */ + if (!(ar = (U_64 *) GET_ELEMENTS_CRITICAL (src))) + goto error; + if (shiftval == 0 + || ((((I_64) ar[len - 1]) >> shiftvalr) == 0 + && (((I_64) ar[len - 1]) << shiftval) > 0)) + shortenedFlag = 1, lenR--; + RELEASE_ELEMENTS_CRITICAL (src, ar, 0); + ar = NULL; + + if (!(resultObject = NEW_OBJECT (lenR))) + goto error; + if (!(ar = (U_64 *) GET_ELEMENTS_CRITICAL (src))) + goto error; + if (!(shifted = (U_64 *) GET_ELEMENTS_CRITICAL (resultObject))) + goto error; + if (shiftval == 0) + { + /* straight copy */ + for (; oldAt < len; oldAt++, newAt++) + shifted[newAt] = ar[oldAt]; + } + else + { + /* zero extend low word */ + shifted[newAt++] = (ar[oldAt++] << shiftval); + for (; oldAt < len; oldAt++, newAt++) + shifted[newAt] = + (ar[oldAt] << shiftval) | (ar[oldAt - 1] >> shiftvalr); + /* sign extend high word */ + if (!shortenedFlag) + shifted[newAt] = (((I_64) ar[oldAt - 1]) >> shiftvalr); + } + + } + else if (shiftval < 0) + { /* shift right */ + shiftval = -shiftval; + oldAt = shiftval / 64, newAt = 0; + shiftval = shiftval % 64; + shiftvalr = 64 - shiftval; + if (oldAt >= len) + { + /* shifting off the end */ + if (!(resultObject = NEW_OBJECT (1))) + goto error; + if (!(shifted = (U_64 *) GET_ELEMENTS_CRITICAL (resultObject))) + goto error; + if (!(ar = (U_64 *) GET_ELEMENTS_CRITICAL (src))) + goto error; + shifted[0] = (((I_64) ar[len - 1]) < 0) ? -1 : 0; + RELEASE_ELEMENTS_CRITICAL (src, ar, 0); + RELEASE_ELEMENTS_CRITICAL (resultObject, shifted, 1); + return resultObject; + } + else + { + lenR = len - oldAt; + if (lenR <= 1) + lenR = 1; + else + { + /* attemp to pre-normalize */ + if (!(ar = (U_64 *) GET_ELEMENTS_CRITICAL (src))) + goto error; + if (shiftval != 0 + && ((((I_64) ar[len - 1]) >> shiftval) == 0 + && (((I_64) ar[len - 1]) << shiftvalr) > 0)) + shortenedFlag = 1, lenR--; + RELEASE_ELEMENTS_CRITICAL (src, ar, 0); + ar = NULL; + } + + if (!(resultObject = NEW_OBJECT (lenR))) + goto error; + if (!(ar = (U_64 *) GET_ELEMENTS_CRITICAL (src))) + goto error; + if (!(shifted = (U_64 *) GET_ELEMENTS_CRITICAL (resultObject))) + goto error; + if (shiftval == 0) + { + /* straight copy */ + for (; oldAt < len; oldAt++, newAt++) + shifted[newAt] = ar[oldAt]; + } + else + { + for (; oldAt < len - 1; oldAt++, newAt++) + shifted[newAt] = + (ar[oldAt] >> shiftval) | (ar[oldAt + 1] << shiftvalr); + /* sign extend high word */ + if (!shortenedFlag) + shifted[newAt] = (((I_64) ar[oldAt]) >> shiftval); + } + } + } + else + { + /* shift by zero - do nothing */ + return src; + } + + RELEASE_ELEMENTS_CRITICAL (src, ar, 0); + RELEASE_ELEMENTS_CRITICAL (resultObject, shifted, 1); + + /* ensure result is normalized */ + if (!(resultObject = internalBigIntegerNormalize (env, resultObject))) + return NULL; + return resultObject; + +error: + if (ar) + RELEASE_ELEMENTS_CRITICAL (src, ar, 0); + if (shifted) + RELEASE_ELEMENTS_CRITICAL (resultObject, shifted, 0); + return NULL; +} + +jlongArray JNICALL +Java_com_ibm_oti_util_math_BigInteger_subImpl (JNIEnv * env, jclass cls, + jlongArray src1, + jlongArray src2) +{ + jlongArray negSrc2; + negSrc2 = internalBigIntegerNeg (env, src2); + if (!negSrc2) /* OutOfMemory exception was thrown */ + return NULL; + /* add returns normalized number, so we don't need to renormalize */ + return internalBigIntegerAdd (env, src1, negSrc2); +} + +static U_32 +internalIntegerAddWithCarry (U_32 a1, U_32 a2, U_32 * carry) +{ + U_32 result = a1 + a2 + *carry; + *carry = ((a1 > result) || ((a1 == result) && (*carry == 1))) ? 1 : 0; + return (result); +} + +static U_32 +internalIntegerSubtractWithCarry (U_32 a1, U_32 a2, U_32 * carry) +{ + U_32 result = a1 - a2 - *carry; + *carry = ((a2 > a1) || ((a2 == a1) && (*carry == 1))) ? 1 : 0; + return (result); +} + +jlongArray +internalBigIntegerNormalize (JNIEnv * env, jlongArray src1) +{ + IDATA len1, lenR; + jlong *ar1, *arR; + IDATA neg1 = 0, i; + jlongArray resultObject = NULL; + + len1 = GET_LENGTH (src1); + if (!(ar1 = (jlong *) GET_ELEMENTS_CRITICAL (src1))) + goto done; + neg1 = IS_NEGATIVE (ar1, len1); + + lenR = len1; + if (neg1) + { + while (lenR >= 2 && ar1[lenR - 1] == -1L && ar1[lenR - 2] < 0L) + { + lenR--; + } + } + else + { + while (lenR >= 2 && ar1[lenR - 1] == 0L && ar1[lenR - 2] >= 0L) + { + lenR--; + } + } + RELEASE_ELEMENTS_CRITICAL (src1, ar1, 0); + if (lenR == len1) + return src1; + + if (!(resultObject = NEW_OBJECT (lenR))) + goto done; + if (!(ar1 = (jlong *) GET_ELEMENTS_CRITICAL (src1))) + goto done; + if (!(arR = (jlong *) GET_ELEMENTS_CRITICAL (resultObject))) + goto release1; + memcpy (arR, ar1, lenR * sizeof (jlong)); + RELEASE_ELEMENTS_CRITICAL (resultObject, arR, 0); + +release1: + RELEASE_ELEMENTS_CRITICAL (src1, ar1, 0); +done: + return resultObject; +} + +jlongArray +grow (JNIEnv * env, jlongArray src1, jlong element) +{ + IDATA len1, lenR; + jlong *ar1, *arR; + jlongArray resultObject = NULL; + + len1 = GET_LENGTH (src1); + if (!(resultObject = NEW_OBJECT (len1 + 1))) + goto done; + + if (!(ar1 = (jlong *) GET_ELEMENTS_CRITICAL (src1))) + goto done; + if (!(arR = (jlong *) GET_ELEMENTS_CRITICAL (resultObject))) + goto release1; + memcpy (arR, ar1, len1 * sizeof (jlong)); + arR[len1] = element; + RELEASE_ELEMENTS_CRITICAL (resultObject, arR, 0); + +release1: + RELEASE_ELEMENTS_CRITICAL (src1, ar1, 0); +done: + return resultObject; +} + +jlongArray +internalBigIntegerAdd (JNIEnv * env, jlongArray src1, jlongArray src2) +{ + IDATA len1, len2; + U_64 *ar1, *ar2, *arR, s, s2, r; + IDATA neg1, neg2, negR, i; + jlongArray resultObject = NULL; + U_32 carry = 0; + + len1 = GET_LENGTH (src1); + len2 = GET_LENGTH (src2); + if (len2 > len1) + { + /* Swap src1 and src2, so src1 is longer */ + void *temp; + IDATA tempint; + temp = src1; + src1 = src2; + src2 = temp; + tempint = len1; + len1 = len2; + len2 = tempint; + } + + if (!(resultObject = NEW_OBJECT (len1))) + goto done; + + if (!(ar1 = (U_64 *) GET_ELEMENTS_CRITICAL (src1))) + goto done; + if (!(ar2 = (U_64 *) GET_ELEMENTS_CRITICAL (src2))) + goto release1; + if (!(arR = (U_64 *) GET_ELEMENTS_CRITICAL (resultObject))) + goto release2; + + for (i = 0; i < len2; i++) + { + arR[i] = r = (s = ar1[i]) + ar2[i] + carry; + carry = s > r || (s == r && carry == 1); + } + + neg2 = IS_NEGATIVE (ar2, len2); + s2 = neg2 ? -1 : 0; + for (i = len2; i < len1; i++) + { + arR[i] = r = (s = ar1[i]) + s2 + carry; + carry = s > r || (s == r && carry == 1); + } + + neg1 = IS_NEGATIVE (ar1, len1); + RELEASE_ELEMENTS_CRITICAL (src2, ar2, 0); + RELEASE_ELEMENTS_CRITICAL (src1, ar1, 0); + + negR = IS_NEGATIVE (arR, len1); + RELEASE_ELEMENTS_CRITICAL (resultObject, arR, 0); + + if (!neg1 && !neg2) + { + if (negR) + { + resultObject = grow (env, resultObject, 0); + } + } + else if (neg1 && neg2) + { + if (!negR) + { + resultObject = grow (env, resultObject, -1); + } + } + return internalBigIntegerNormalize (env, resultObject); + +release2: + RELEASE_ELEMENTS_CRITICAL (src2, ar2, 0); +release1: + RELEASE_ELEMENTS_CRITICAL (src1, ar1, 0); +done: + return resultObject; +} + +jlongArray +internalBigIntegerNeg (JNIEnv * env, jlongArray src1) +{ + IDATA len1; + U_64 *ar1, *arN, *arO; + IDATA i; + jlongArray negObject, oneObject; + jlongArray resultObject = NULL; + + len1 = GET_LENGTH (src1); + if (!(negObject = NEW_OBJECT (len1))) + goto done; + if (!(oneObject = NEW_OBJECT (1))) + goto done; + + if (!(ar1 = (U_64 *) GET_ELEMENTS_CRITICAL (src1))) + goto done; + if (!(arN = (U_64 *) GET_ELEMENTS_CRITICAL (negObject))) + goto release1; + if (!(arO = (U_64 *) GET_ELEMENTS_CRITICAL (oneObject))) + goto releaseN; + arO[0] = 1; + RELEASE_ELEMENTS_CRITICAL (oneObject, arO, 0); + + for (i = 0; i < len1; i++) + { + arN[i] = ~ar1[i]; + } + RELEASE_ELEMENTS_CRITICAL (negObject, arN, 0); + RELEASE_ELEMENTS_CRITICAL (src1, ar1, 0); + + resultObject = internalBigIntegerAdd (env, negObject, oneObject); + return resultObject; + +error: + RELEASE_ELEMENTS_CRITICAL (oneObject, arO, 0); +releaseN: + RELEASE_ELEMENTS_CRITICAL (negObject, arN, 0); +release1: + RELEASE_ELEMENTS_CRITICAL (src1, ar1, 0); +done: + return resultObject; +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/bigint.h URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/bigint.h?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/bigint.h (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/bigint.h Wed Nov 30 21:29:27 2005 @@ -0,0 +1,36 @@ +/* Copyright 1991, 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if !defined(bigint_h) +#define bigint_h +jlongArray JNICALL Java_com_ibm_oti_util_math_BigInteger_subImpl +PROTOTYPE ((JNIEnv * env, jclass cls, jlongArray src1, jlongArray src2)); +jlongArray JNICALL Java_com_ibm_oti_util_math_BigInteger_divImpl +PROTOTYPE ((JNIEnv * env, jclass cls, jlongArray topObject, + jlongArray bottomObject)); +jlongArray JNICALL Java_com_ibm_oti_util_math_BigInteger_mulImpl +PROTOTYPE ((JNIEnv * env, jclass cls, jlongArray src1, jlongArray src2)); +jlongArray JNICALL Java_com_ibm_oti_util_math_BigInteger_negImpl +PROTOTYPE ((JNIEnv * env, jclass cls, jlongArray src)); +jlongArray JNICALL Java_com_ibm_oti_util_math_BigInteger_addImpl +PROTOTYPE ((JNIEnv * env, jclass cls, jlongArray src1, jlongArray src2)); +jlongArray JNICALL Java_com_ibm_oti_util_math_BigInteger_remImpl +PROTOTYPE ((JNIEnv * env, jclass cls, jlongArray topObject, + jlongArray bottomObject)); +jlongArray JNICALL Java_com_ibm_oti_util_math_BigInteger_shlImpl +PROTOTYPE ((JNIEnv * env, jclass cls, jlongArray src, jint shiftval)); +jint JNICALL Java_com_ibm_oti_util_math_BigInteger_compImpl +PROTOTYPE ((JNIEnv * env, jclass cls, jlongArray src1, jlongArray src2)); +#endif /* bigint_h */ Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/cbigint.c URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/cbigint.c?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/cbigint.c (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/cbigint.c Wed Nov 30 21:29:27 2005 @@ -0,0 +1,866 @@ +/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cbigint.h" + +#if defined(LINUX) +#define USE_LL +#endif + +#define at(i) (i) + +#define HIGH_IN_U64(u64) ((u64) >> 32) +#if defined(USE_LL) +#define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFFLL) +#else +#if defined(USE_L) +#define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFFL) +#else +#define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFF) +#endif /* USE_L */ +#endif /* USE_LL */ + +#if defined(USE_LL) +#define TEN_E1 (0xALL) +#define TEN_E2 (0x64LL) +#define TEN_E3 (0x3E8LL) +#define TEN_E4 (0x2710LL) +#define TEN_E5 (0x186A0LL) +#define TEN_E6 (0xF4240LL) +#define TEN_E7 (0x989680LL) +#define TEN_E8 (0x5F5E100LL) +#define TEN_E9 (0x3B9ACA00LL) +#define TEN_E19 (0x8AC7230489E80000LL) +#else +#if defined(USE_L) +#define TEN_E1 (0xAL) +#define TEN_E2 (0x64L) +#define TEN_E3 (0x3E8L) +#define TEN_E4 (0x2710L) +#define TEN_E5 (0x186A0L) +#define TEN_E6 (0xF4240L) +#define TEN_E7 (0x989680L) +#define TEN_E8 (0x5F5E100L) +#define TEN_E9 (0x3B9ACA00L) +#define TEN_E19 (0x8AC7230489E80000L) +#else +#define TEN_E1 (0xA) +#define TEN_E2 (0x64) +#define TEN_E3 (0x3E8) +#define TEN_E4 (0x2710) +#define TEN_E5 (0x186A0) +#define TEN_E6 (0xF4240) +#define TEN_E7 (0x989680) +#define TEN_E8 (0x5F5E100) +#define TEN_E9 (0x3B9ACA00) +#define TEN_E19 (0x8AC7230489E80000) +#endif /* USE_L */ +#endif /* USE_LL */ + +#define TIMES_TEN(x) (((x) << 3) + ((x) << 1)) +#define bitSection(x, mask, shift) (((x) & (mask)) >> (shift)) +#define DOUBLE_TO_LONGBITS(dbl) (*((U_64 *)(&dbl))) +#define FLOAT_TO_INTBITS(flt) (*((U_32 *)(&flt))) +#define CREATE_DOUBLE_BITS(normalizedM, e) (((normalizedM) & MANTISSA_MASK) | (((U_64)((e) + E_OFFSET)) << 52)) + +#if defined(USE_LL) +#define MANTISSA_MASK (0x000FFFFFFFFFFFFFLL) +#define EXPONENT_MASK (0x7FF0000000000000LL) +#define NORMAL_MASK (0x0010000000000000LL) +#define SIGN_MASK (0x8000000000000000LL) +#else +#if defined(USE_L) +#define MANTISSA_MASK (0x000FFFFFFFFFFFFFL) +#define EXPONENT_MASK (0x7FF0000000000000L) +#define NORMAL_MASK (0x0010000000000000L) +#define SIGN_MASK (0x8000000000000000L) +#else +#define MANTISSA_MASK (0x000FFFFFFFFFFFFF) +#define EXPONENT_MASK (0x7FF0000000000000) +#define NORMAL_MASK (0x0010000000000000) +#define SIGN_MASK (0x8000000000000000) +#endif /* USE_L */ +#endif /* USE_LL */ + +#define E_OFFSET (1075) + +#define FLOAT_MANTISSA_MASK (0x007FFFFF) +#define FLOAT_EXPONENT_MASK (0x7F800000) +#define FLOAT_NORMAL_MASK (0x00800000) +#define FLOAT_E_OFFSET (150) + +IDATA +simpleAddHighPrecision (U_64 * arg1, IDATA length, U_64 arg2) +{ + /* assumes length > 0 */ + IDATA index = 1; + + *arg1 += arg2; + if (arg2 <= *arg1) + return 0; + else if (length == 1) + return 1; + + while (++arg1[index] == 0 && ++index < length); + + return (IDATA) index == length; +} + +IDATA +addHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2) +{ + /* addition is limited by length of arg1 as it this function is + * storing the result in arg1 */ + /* fix for cc (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7): code generated does not + * do the temp1 + temp2 + carry addition correct. carry is 64 bit because gcc has + * subtle issues when you mix 64 / 32 bit maths. */ + U_64 temp1, temp2, temp3; /* temporary variables to help the SH-4, and gcc */ + U_64 carry; + IDATA index; + + if (length1 == 0 || length2 == 0) + { + return 0; + } + else if (length1 < length2) + { + length2 = length1; + } + + carry = 0; + index = 0; + do + { + temp1 = arg1[index]; + temp2 = arg2[index]; + temp3 = temp1 + temp2; + arg1[index] = temp3 + carry; + if (arg2[index] < arg1[index]) + carry = 0; + else if (arg2[index] != arg1[index]) + carry = 1; + } + while (++index < length2); + if (!carry) + return 0; + else if (index == length1) + return 1; + + while (++arg1[index] == 0 && ++index < length1); + + return (IDATA) index == length1; +} + +void +subtractHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2) +{ + /* assumes arg1 > arg2 */ + IDATA index; + for (index = 0; index < length1; ++index) + arg1[index] = ~arg1[index]; + simpleAddHighPrecision (arg1, length1, 1); + + while (length2 > 0 && arg2[length2 - 1] == 0) + --length2; + + addHighPrecision (arg1, length1, arg2, length2); + + for (index = 0; index < length1; ++index) + arg1[index] = ~arg1[index]; + simpleAddHighPrecision (arg1, length1, 1); +} + +U_32 +simpleMultiplyHighPrecision (U_64 * arg1, IDATA length, U_64 arg2) +{ + /* assumes arg2 only holds 32 bits of information */ + U_64 product; + IDATA index; + + index = 0; + product = 0; + + do + { + product = + HIGH_IN_U64 (product) + arg2 * LOW_U32_FROM_PTR (arg1 + index); + LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (product); + product = + HIGH_IN_U64 (product) + arg2 * HIGH_U32_FROM_PTR (arg1 + index); + HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (product); + } + while (++index < length); + + return HIGH_U32_FROM_VAR (product); +} + +void +simpleMultiplyAddHighPrecision (U_64 * arg1, IDATA length, U_64 arg2, + U_32 * result) +{ + /* Assumes result can hold the product and arg2 only holds 32 bits + of information */ + U_64 product; + IDATA index, resultIndex; + + index = resultIndex = 0; + product = 0; + + do + { + product = + HIGH_IN_U64 (product) + result[at (resultIndex)] + + arg2 * LOW_U32_FROM_PTR (arg1 + index); + result[at (resultIndex)] = LOW_U32_FROM_VAR (product); + ++resultIndex; + product = + HIGH_IN_U64 (product) + result[at (resultIndex)] + + arg2 * HIGH_U32_FROM_PTR (arg1 + index); + result[at (resultIndex)] = LOW_U32_FROM_VAR (product); + ++resultIndex; + } + while (++index < length); + + result[at (resultIndex)] += HIGH_U32_FROM_VAR (product); + if (result[at (resultIndex)] < HIGH_U32_FROM_VAR (product)) + { + /* must be careful with ++ operator and macro expansion */ + ++resultIndex; + while (++result[at (resultIndex)] == 0) + ++resultIndex; + } +} + +void +multiplyHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2, + U_64 * result, IDATA length) +{ + /* assumes result is large enough to hold product */ + U_64 *temp; + U_32 *resultIn32; + IDATA count, index; + + if (length1 < length2) + { + temp = arg1; + arg1 = arg2; + arg2 = temp; + count = length1; + length1 = length2; + length2 = count; + } + + memset (result, 0, sizeof (U_64) * length); + + /* length1 > length2 */ + resultIn32 = (U_32 *) result; + index = -1; + for (count = 0; count < length2; ++count) + { + simpleMultiplyAddHighPrecision (arg1, length1, LOW_IN_U64 (arg2[count]), + resultIn32 + (++index)); + simpleMultiplyAddHighPrecision (arg1, length1, + HIGH_IN_U64 (arg2[count]), + resultIn32 + (++index)); + + } +} + +U_32 +simpleAppendDecimalDigitHighPrecision (U_64 * arg1, IDATA length, U_64 digit) +{ + /* assumes digit is less than 32 bits */ + U_64 arg; + IDATA index = 0; + + digit <<= 32; + do + { + arg = LOW_IN_U64 (arg1[index]); + digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg); + LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit); + + arg = HIGH_IN_U64 (arg1[index]); + digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg); + HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit); + } + while (++index < length); + + return HIGH_U32_FROM_VAR (digit); +} + +void +simpleShiftLeftHighPrecision (U_64 * arg1, IDATA length, IDATA arg2) +{ + /* assumes length > 0 */ + IDATA index, offset; + if (arg2 >= 64) + { + offset = arg2 >> 6; + index = length; + + while (--index - offset >= 0) + arg1[index] = arg1[index - offset]; + do + { + arg1[index] = 0; + } + while (--index >= 0); + + arg2 &= 0x3F; + } + + if (arg2 == 0) + return; + while (--length > 0) + { + arg1[length] = arg1[length] << arg2 | arg1[length - 1] >> (64 - arg2); + } + *arg1 <<= arg2; +} + +IDATA +highestSetBit (U_64 * y) +{ + U_32 x; + IDATA result; + + if (*y == 0) + return 0; + +#if defined(USE_LL) + if (*y & 0xFFFFFFFF00000000LL) + { + x = HIGH_U32_FROM_PTR (y); + result = 32; + } + else + { + x = LOW_U32_FROM_PTR (y); + result = 0; + } +#else +#if defined(USE_L) + if (*y & 0xFFFFFFFF00000000L) + { + x = HIGH_U32_FROM_PTR (y); + result = 32; + } + else + { + x = LOW_U32_FROM_PTR (y); + result = 0; + } +#else + if (*y & 0xFFFFFFFF00000000) + { + x = HIGH_U32_FROM_PTR (y); + result = 32; + } + else + { + x = LOW_U32_FROM_PTR (y); + result = 0; + } +#endif /* USE_L */ +#endif /* USE_LL */ + + if (x & 0xFFFF0000) + { + x = bitSection (x, 0xFFFF0000, 16); + result += 16; + } + if (x & 0xFF00) + { + x = bitSection (x, 0xFF00, 8); + result += 8; + } + if (x & 0xF0) + { + x = bitSection (x, 0xF0, 4); + result += 4; + } + if (x > 0x7) + return result + 4; + else if (x > 0x3) + return result + 3; + else if (x > 0x1) + return result + 2; + else + return result + 1; +} + +IDATA +lowestSetBit (U_64 * y) +{ + U_32 x; + IDATA result; + + if (*y == 0) + return 0; + +#if defined(USE_LL) + if (*y & 0x00000000FFFFFFFFLL) + { + x = LOW_U32_FROM_PTR (y); + result = 0; + } + else + { + x = HIGH_U32_FROM_PTR (y); + result = 32; + } +#else +#if defined(USE_L) + if (*y & 0x00000000FFFFFFFFL) + { + x = LOW_U32_FROM_PTR (y); + result = 0; + } + else + { + x = HIGH_U32_FROM_PTR (y); + result = 32; + } +#else + if (*y & 0x00000000FFFFFFFF) + { + x = LOW_U32_FROM_PTR (y); + result = 0; + } + else + { + x = HIGH_U32_FROM_PTR (y); + result = 32; + } +#endif /* USE_L */ +#endif /* USE_LL */ + + if (!(x & 0xFFFF)) + { + x = bitSection (x, 0xFFFF0000, 16); + result += 16; + } + if (!(x & 0xFF)) + { + x = bitSection (x, 0xFF00, 8); + result += 8; + } + if (!(x & 0xF)) + { + x = bitSection (x, 0xF0, 4); + result += 4; + } + + if (x & 0x1) + return result + 1; + else if (x & 0x2) + return result + 2; + else if (x & 0x4) + return result + 3; + else + return result + 4; +} + +IDATA +highestSetBitHighPrecision (U_64 * arg, IDATA length) +{ + IDATA highBit; + + while (--length >= 0) + { + highBit = highestSetBit (arg + length); + if (highBit) + return highBit + 64 * length; + } + + return 0; +} + +IDATA +lowestSetBitHighPrecision (U_64 * arg, IDATA length) +{ + IDATA lowBit, index = -1; + + while (++index < length) + { + lowBit = lowestSetBit (arg + index); + if (lowBit) + return lowBit + 64 * index; + } + + return 0; +} + +IDATA +compareHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2) +{ + while (--length1 >= 0 && arg1[length1] == 0); + while (--length2 >= 0 && arg2[length2] == 0); + + if (length1 > length2) + return 1; + else if (length1 < length2) + return -1; + else if (length1 > -1) + { + do + { + if (arg1[length1] > arg2[length1]) + return 1; + else if (arg1[length1] < arg2[length1]) + return -1; + } + while (--length1 >= 0); + } + + return 0; +} + +jdouble +toDoubleHighPrecision (U_64 * arg, IDATA length) +{ + IDATA highBit; + U_64 mantissa, test64; + U_32 test; + jdouble result; + + while (length > 0 && arg[length - 1] == 0) + --length; + + if (length == 0) + result = 0.0; + else if (length > 16) + { + DOUBLE_TO_LONGBITS (result) = EXPONENT_MASK; + } + else if (length == 1) + { + highBit = highestSetBit (arg); + if (highBit <= 53) + { + highBit = 53 - highBit; + mantissa = *arg << highBit; + DOUBLE_TO_LONGBITS (result) = + CREATE_DOUBLE_BITS (mantissa, -highBit); + } + else + { + highBit -= 53; + mantissa = *arg >> highBit; + DOUBLE_TO_LONGBITS (result) = + CREATE_DOUBLE_BITS (mantissa, highBit); + + /* perform rounding, round to even in case of tie */ + test = (LOW_U32_FROM_PTR (arg) << (11 - highBit)) & 0x7FF; + if (test > 0x400 || ((test == 0x400) && (mantissa & 1))) + DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; + } + } + else + { + highBit = highestSetBit (arg + (--length)); + if (highBit <= 53) + { + highBit = 53 - highBit; + if (highBit > 0) + { + mantissa = + (arg[length] << highBit) | (arg[length - 1] >> + (64 - highBit)); + } + else + { + mantissa = arg[length]; + } + DOUBLE_TO_LONGBITS (result) = + CREATE_DOUBLE_BITS (mantissa, length * 64 - highBit); + + /* perform rounding, round to even in case of tie */ + test64 = arg[--length] << highBit; + if (test64 > SIGN_MASK || ((test64 == SIGN_MASK) && (mantissa & 1))) + DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; + else if (test64 == SIGN_MASK) + { + while (--length >= 0) + { + if (arg[length] != 0) + { + DOUBLE_TO_LONGBITS (result) = + DOUBLE_TO_LONGBITS (result) + 1; + break; + } + } + } + } + else + { + highBit -= 53; + mantissa = arg[length] >> highBit; + DOUBLE_TO_LONGBITS (result) = + CREATE_DOUBLE_BITS (mantissa, length * 64 + highBit); + + /* perform rounding, round to even in case of tie */ + test = (LOW_U32_FROM_PTR (arg + length) << (11 - highBit)) & 0x7FF; + if (test > 0x400 || ((test == 0x400) && (mantissa & 1))) + DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; + else if (test == 0x400) + { + do + { + if (arg[--length] != 0) + { + DOUBLE_TO_LONGBITS (result) = + DOUBLE_TO_LONGBITS (result) + 1; + break; + } + } + while (length > 0); + } + } + } + + return result; +} + +IDATA +tenToTheEHighPrecision (U_64 * result, IDATA length, jint e) +{ + /* size test */ + if (length < ((e / 19) + 1)) + return 0; + + memset (result, 0, length * sizeof (U_64)); + *result = 1; + + if (e == 0) + return 1; + + length = 1; + length = timesTenToTheEHighPrecision (result, length, e); + /* bad O(n) way of doing it, but simple */ + /* + do { + overflow = simpleAppendDecimalDigitHighPrecision(result, length, 0); + if (overflow) + result[length++] = overflow; + } while (--e); + */ + return length; +} + +IDATA +timesTenToTheEHighPrecision (U_64 * result, IDATA length, jint e) +{ + /* assumes result can hold value */ + U_64 overflow; + int exp10 = e; + + if (e == 0) + return length; + + /* bad O(n) way of doing it, but simple */ + /* + do { + overflow = simpleAppendDecimalDigitHighPrecision(result, length, 0); + if (overflow) + result[length++] = overflow; + } while (--e); + */ + /* Replace the current implementaion which performs a + * "multiplication" by 10 e number of times with an actual + * mulitplication. 10e19 is the largest exponent to the power of ten + * that will fit in a 64-bit integer, and 10e9 is the largest exponent to + * the power of ten that will fit in a 64-bit integer. Not sure where the + * break-even point is between an actual multiplication and a + * simpleAappendDecimalDigit() so just pick 10e3 as that point for + * now. + */ + while (exp10 >= 19) + { + overflow = simpleMultiplyHighPrecision64 (result, length, TEN_E19); + if (overflow) + result[length++] = overflow; + exp10 -= 19; + } + while (exp10 >= 9) + { + overflow = simpleMultiplyHighPrecision (result, length, TEN_E9); + if (overflow) + result[length++] = overflow; + exp10 -= 9; + } + if (exp10 == 0) + return length; + else if (exp10 == 1) + { + overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0); + if (overflow) + result[length++] = overflow; + } + else if (exp10 == 2) + { + overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0); + if (overflow) + result[length++] = overflow; + overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0); + if (overflow) + result[length++] = overflow; + } + else if (exp10 == 3) + { + overflow = simpleMultiplyHighPrecision (result, length, TEN_E3); + if (overflow) + result[length++] = overflow; + } + else if (exp10 == 4) + { + overflow = simpleMultiplyHighPrecision (result, length, TEN_E4); + if (overflow) + result[length++] = overflow; + } + else if (exp10 == 5) + { + overflow = simpleMultiplyHighPrecision (result, length, TEN_E5); + if (overflow) + result[length++] = overflow; + } + else if (exp10 == 6) + { + overflow = simpleMultiplyHighPrecision (result, length, TEN_E6); + if (overflow) + result[length++] = overflow; + } + else if (exp10 == 7) + { + overflow = simpleMultiplyHighPrecision (result, length, TEN_E7); + if (overflow) + result[length++] = overflow; + } + else if (exp10 == 8) + { + overflow = simpleMultiplyHighPrecision (result, length, TEN_E8); + if (overflow) + result[length++] = overflow; + } + return length; +} + +U_64 +doubleMantissa (jdouble z) +{ + U_64 m = DOUBLE_TO_LONGBITS (z); + + if ((m & EXPONENT_MASK) != 0) + m = (m & MANTISSA_MASK) | NORMAL_MASK; + else + m = (m & MANTISSA_MASK); + + return m; +} + +IDATA +doubleExponent (jdouble z) +{ + /* assumes positive double */ + IDATA k = HIGH_U32_FROM_VAR (z) >> 20; + + if (k) + k -= E_OFFSET; + else + k = 1 - E_OFFSET; + + return k; +} + +UDATA +floatMantissa (jfloat z) +{ + UDATA m = (UDATA) FLOAT_TO_INTBITS (z); + + if ((m & FLOAT_EXPONENT_MASK) != 0) + m = (m & FLOAT_MANTISSA_MASK) | FLOAT_NORMAL_MASK; + else + m = (m & FLOAT_MANTISSA_MASK); + + return m; +} + +IDATA +floatExponent (jfloat z) +{ + /* assumes positive float */ + IDATA k = FLOAT_TO_INTBITS (z) >> 23; + if (k) + k -= FLOAT_E_OFFSET; + else + k = 1 - FLOAT_E_OFFSET; + + return k; +} + +/* Allow a 64-bit value in arg2 */ +U_64 +simpleMultiplyHighPrecision64 (U_64 * arg1, IDATA length, U_64 arg2) +{ + U_64 intermediate, *pArg1, carry1, carry2, prod1, prod2, sum; + IDATA index; + U_32 buf32; + + index = 0; + intermediate = 0; + pArg1 = arg1 + index; + carry1 = carry2 = 0; + + do + { + if ((*pArg1 != 0) || (intermediate != 0)) + { + prod1 = + (U_64) LOW_U32_FROM_VAR (arg2) * (U_64) LOW_U32_FROM_PTR (pArg1); + sum = intermediate + prod1; + if ((sum < prod1) || (sum < intermediate)) + { + carry1 = 1; + } + else + { + carry1 = 0; + } + prod1 = + (U_64) LOW_U32_FROM_VAR (arg2) * (U_64) HIGH_U32_FROM_PTR (pArg1); + prod2 = + (U_64) HIGH_U32_FROM_VAR (arg2) * (U_64) LOW_U32_FROM_PTR (pArg1); + intermediate = carry2 + HIGH_IN_U64 (sum) + prod1 + prod2; + if ((intermediate < prod1) || (intermediate < prod2)) + { + carry2 = 1; + } + else + { + carry2 = 0; + } + LOW_U32_FROM_PTR (pArg1) = LOW_U32_FROM_VAR (sum); + buf32 = HIGH_U32_FROM_PTR (pArg1); + HIGH_U32_FROM_PTR (pArg1) = LOW_U32_FROM_VAR (intermediate); + intermediate = carry1 + HIGH_IN_U64 (intermediate) + + (U_64) HIGH_U32_FROM_VAR (arg2) * (U_64) buf32; + } + pArg1++; + } + while (++index < length); + return intermediate; +} Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/cbigint.h URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/cbigint.h?rev=350181&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/cbigint.h (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/linux.IA32/math/cbigint.h Wed Nov 30 21:29:27 2005 @@ -0,0 +1,60 @@ +/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if !defined(cbigint_h) +#define cbigint_h +#include "fltconst.h" +#include "jcl.h" +#define LOW_U32_FROM_VAR(u64) LOW_U32_FROM_LONG64(u64) +#define LOW_U32_FROM_PTR(u64ptr) LOW_U32_FROM_LONG64_PTR(u64ptr) +#define HIGH_U32_FROM_VAR(u64) HIGH_U32_FROM_LONG64(u64) +#define HIGH_U32_FROM_PTR(u64ptr) HIGH_U32_FROM_LONG64_PTR(u64ptr) +#if defined(__cplusplus) +extern "C" +{ +#endif + void multiplyHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, + IDATA length2, U_64 * result, IDATA length); + U_32 simpleAppendDecimalDigitHighPrecision (U_64 * arg1, IDATA length, + U_64 digit); + jdouble toDoubleHighPrecision (U_64 * arg, IDATA length); + IDATA tenToTheEHighPrecision (U_64 * result, IDATA length, jint e); + U_64 doubleMantissa (jdouble z); + IDATA compareHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, + IDATA length2); + IDATA highestSetBitHighPrecision (U_64 * arg, IDATA length); + void subtractHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, + IDATA length2); + IDATA doubleExponent (jdouble z); + U_32 simpleMultiplyHighPrecision (U_64 * arg1, IDATA length, U_64 arg2); + IDATA addHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, + IDATA length2); + void simpleMultiplyAddHighPrecisionBigEndianFix (U_64 * arg1, IDATA length, + U_64 arg2, U_32 * result); + IDATA lowestSetBit (U_64 * y); + IDATA timesTenToTheEHighPrecision (U_64 * result, IDATA length, jint e); + void simpleMultiplyAddHighPrecision (U_64 * arg1, IDATA length, U_64 arg2, + U_32 * result); + IDATA highestSetBit (U_64 * y); + IDATA lowestSetBitHighPrecision (U_64 * arg, IDATA length); + void simpleShiftLeftHighPrecision (U_64 * arg1, IDATA length, IDATA arg2); + UDATA floatMantissa (jfloat z); + U_64 simpleMultiplyHighPrecision64 (U_64 * arg1, IDATA length, U_64 arg2); + IDATA simpleAddHighPrecision (U_64 * arg1, IDATA length, U_64 arg2); + IDATA floatExponent (jfloat z); +#if defined(__cplusplus) +} +#endif +#endif /* cbigint_h */