You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2005/12/01 07:04:00 UTC
svn commit: r350181 [183/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....
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/bigint.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/bigint.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/bigint.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/bigint.c Wed Nov 30 21:29:27 2005
@@ -0,0 +1,1278 @@
+/* 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;
+ 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;
+ 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;
+
+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/win.IA32/math/bigint.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/bigint.h?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/bigint.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/bigint.h Wed Nov 30 21:29:27 2005
@@ -0,0 +1,38 @@
+/* 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/win.IA32/math/cbigint.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/cbigint.c?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/cbigint.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.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 <string.h>
+#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;
+ 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/win.IA32/math/cbigint.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/cbigint.h?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/cbigint.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/native-src/win.IA32/math/cbigint.h Wed Nov 30 21:29:27 2005
@@ -0,0 +1,64 @@
+/* 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 */