summaryrefslogtreecommitdiff
path: root/tests/nbody-java/xmlvm-number.c
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-05-08 16:06:26 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-05-08 16:06:26 -0700
commit693682fc225e60c9c335ee910fb3c8bb5cf85470 (patch)
treeb2c1285adf65b68a7b20aa231c4c5665966b2c18 /tests/nbody-java/xmlvm-number.c
parentb41b535aeac53740dec416f617378ec4e4e382ce (diff)
add nbody-java code
Diffstat (limited to 'tests/nbody-java/xmlvm-number.c')
-rw-r--r--tests/nbody-java/xmlvm-number.c327
1 files changed, 327 insertions, 0 deletions
diff --git a/tests/nbody-java/xmlvm-number.c b/tests/nbody-java/xmlvm-number.c
new file mode 100644
index 00000000..ae496d54
--- /dev/null
+++ b/tests/nbody-java/xmlvm-number.c
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ * cbigint.c has been adapted for xmlvm
+ */
+#include "xmlvm-number.h"
+
+
+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 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;
+}
+
+
+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;
+}
+
+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);
+}
+
+IDATA timesTenToTheEHighPrecision (U_64 * result, IDATA length, JAVA_INT e)
+{
+ /* assumes result can hold value */
+ U_64 overflow;
+ int exp10 = e;
+
+ if (e == 0)
+ return length;
+
+ 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;
+}
+
+IDATA addHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2)
+{
+
+ 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;
+}
+
+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;
+}
+
+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;
+}
+
+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);
+}