1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#if !defined(cbigint_h)
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#define cbigint_h
2074c05e2a892f236c8648af7f4cfb2bcb483f267bElliott Hughes
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "JNIHelp.h"
2274c05e2a892f236c8648af7f4cfb2bcb483f267bElliott Hughes
23a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#include <sys/types.h>
24a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#include <sys/param.h>
25a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#include <stdint.h>
26a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes
27a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes/* IEEE floats consist of: sign bit, exponent field, significand field
28a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    single:  31 = sign bit, 30..23 = exponent (8 bits), 22..0 = significand (23 bits)
29a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    double:  63 = sign bit, 62..52 = exponent (11 bits), 51..0 = significand (52 bits)
30a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    inf                ==    (all exponent bits set) and (all mantissa bits clear)
31a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    nan                ==    (all exponent bits set) and (at least one mantissa bit set)
32a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    finite             ==    (at least one exponent bit clear)
33a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    zero               ==    (all exponent bits clear) and (all mantissa bits clear)
34a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    denormal           ==    (all exponent bits clear) and (at least one mantissa bit set)
35a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    positive           ==    sign bit clear
36a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    negative           ==    sign bit set
37a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes*/
38a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#if __BYTE_ORDER == __LITTLE_ENDIAN
39a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define DOUBLE_LO_OFFSET        0
40a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define DOUBLE_HI_OFFSET        1
41a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LONG_LO_OFFSET          0
42a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LONG_HI_OFFSET          1
43a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#else
44a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define DOUBLE_LO_OFFSET        1
45a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define DOUBLE_HI_OFFSET        0
46a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LONG_LO_OFFSET          1
47a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LONG_HI_OFFSET          0
48a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#endif
49a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes
50a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define DOUBLE_EXPONENT_MASK_HI 0x7FF00000
51a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define DOUBLE_MANTISSA_MASK_HI 0x000FFFFF
52a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes
53a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesunion U64U32DBL {
54a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    uint64_t    u64val;
55a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    uint32_t    u32val[2];
56a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    int32_t    i32val[2];
57a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes    double  dval;
58a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes};
59a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes
60a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define DOUBLE_TO_LONGBITS(dbl) (*(reinterpret_cast<uint64_t*>(&dbl)))
61a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define FLOAT_TO_INTBITS(flt) (*(reinterpret_cast<uint32_t*>(&flt)))
62a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define INTBITS_TO_FLOAT(bits) (*(reinterpret_cast<float*>(&bits)))
63a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes
64a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes/* Replace P_FLOAT_HI and P_FLOAT_LOW */
65a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes/* These macros are used to access the high and low 32-bit parts of a double (64-bit) value. */
66a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LOW_U32_FROM_DBL_PTR(dblptr) ((reinterpret_cast<U64U32DBL*>(dblptr))->u32val[DOUBLE_LO_OFFSET])
67a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define HIGH_U32_FROM_DBL_PTR(dblptr) ((reinterpret_cast<U64U32DBL*>(dblptr))->u32val[DOUBLE_HI_OFFSET])
68a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LOW_I32_FROM_DBL_PTR(dblptr) ((reinterpret_cast<U64U32DBL*>(dblptr))->i32val[DOUBLE_LO_OFFSET])
69a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define HIGH_I32_FROM_DBL_PTR(dblptr) ((reinterpret_cast<U64U32DBL*>(dblptr))->i32val[DOUBLE_HI_OFFSET])
70a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LOW_U32_FROM_DBL(dbl) LOW_U32_FROM_DBL_PTR(&(dbl))
71a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define HIGH_U32_FROM_DBL(dbl) HIGH_U32_FROM_DBL_PTR(&(dbl))
72a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LOW_U32_FROM_LONG64_PTR(long64ptr) ((reinterpret_cast<U64U32DBL*>(long64ptr))->u32val[LONG_LO_OFFSET])
73a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define HIGH_U32_FROM_LONG64_PTR(long64ptr) ((reinterpret_cast<U64U32DBL*>(long64ptr))->u32val[LONG_HI_OFFSET])
74a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LOW_I32_FROM_LONG64_PTR(long64ptr) ((reinterpret_cast<U64U32DBL*>(long64ptr))->i32val[LONG_LO_OFFSET])
75a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define HIGH_I32_FROM_LONG64_PTR(long64ptr) ((reinterpret_cast<U64U32DBL*>(long64ptr))->i32val[LONG_HI_OFFSET])
76a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LOW_U32_FROM_LONG64(long64) LOW_U32_FROM_LONG64_PTR(&(long64))
77a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define HIGH_U32_FROM_LONG64(long64) HIGH_U32_FROM_LONG64_PTR(&(long64))
78a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define LOW_I32_FROM_LONG64(long64) LOW_I32_FROM_LONG64_PTR(&(long64))
79a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define HIGH_I32_FROM_LONG64(long64) HIGH_I32_FROM_LONG64_PTR(&(long64))
80a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define IS_DENORMAL_DBL_PTR(dblptr) (((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_EXPONENT_MASK_HI) == 0) && ((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_MANTISSA_MASK_HI) != 0 || (LOW_U32_FROM_DBL_PTR(dblptr) != 0)))
81a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes#define IS_DENORMAL_DBL(dbl) IS_DENORMAL_DBL_PTR(&(dbl))
82a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#define LOW_U32_FROM_VAR(u64)     LOW_U32_FROM_LONG64(u64)
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#define LOW_U32_FROM_PTR(u64ptr)  LOW_U32_FROM_LONG64_PTR(u64ptr)
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#define HIGH_U32_FROM_VAR(u64)    HIGH_U32_FROM_LONG64(u64)
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#define HIGH_U32_FROM_PTR(u64ptr) HIGH_U32_FROM_LONG64_PTR(u64ptr)
87a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes
88a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesvoid multiplyHighPrecision(uint64_t* arg1, int32_t length1, uint64_t* arg2, int32_t length2,
89a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes        uint64_t* result, int32_t length);
90a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesuint32_t simpleAppendDecimalDigitHighPrecision(uint64_t* arg1, int32_t length, uint64_t digit);
91a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesjdouble toDoubleHighPrecision(uint64_t* arg, int32_t length);
92a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesuint64_t doubleMantissa(jdouble z);
93a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesint32_t compareHighPrecision(uint64_t* arg1, int32_t length1, uint64_t* arg2, int32_t length2);
94a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesint32_t highestSetBitHighPrecision(uint64_t* arg, int32_t length);
95a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesvoid subtractHighPrecision(uint64_t* arg1, int32_t length1, uint64_t* arg2, int32_t length2);
96a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesint32_t doubleExponent(jdouble z);
97a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesint32_t addHighPrecision(uint64_t* arg1, int32_t length1, uint64_t* arg2, int32_t length2);
98a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesint32_t lowestSetBit(uint64_t* y);
99a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesint32_t timesTenToTheEHighPrecision(uint64_t* result, int32_t length, jint e);
100a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesint32_t highestSetBit(uint64_t* y);
101a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesint32_t lowestSetBitHighPrecision(uint64_t* arg, int32_t length);
102a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesvoid simpleShiftLeftHighPrecision(uint64_t* arg1, int32_t length, int32_t arg2);
103a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesuint32_t floatMantissa(jfloat z);
104a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesint32_t simpleAddHighPrecision(uint64_t* arg1, int32_t length, uint64_t arg2);
105a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughesint32_t floatExponent(jfloat z);
106a63f0d99978c3d6e6fcde1f2562295070f8d7e14Elliott Hughes
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#endif                          /* cbigint_h */
108