Search in sources :

Example 1 with Decimal

use of com.amazon.ion.Decimal in project ion-java by amzn.

the class IonReaderBinaryRawX method readDecimal.

protected final Decimal readDecimal(int len) throws IOException {
    MathContext mathContext = MathContext.UNLIMITED;
    Decimal bd;
    // we only write out the '0' value as the nibble 0
    if (len == 0) {
        bd = Decimal.valueOf(0, mathContext);
    } else {
        // otherwise we to it the hard way ....
        long save_limit = NO_LIMIT;
        if (_local_remaining != NO_LIMIT) {
            save_limit = _local_remaining - len;
        }
        _local_remaining = len;
        int exponent = readVarInt();
        BigInteger value;
        int signum;
        if (_local_remaining > 0) {
            byte[] bits = new byte[(int) _local_remaining];
            readAll(bits, 0, (int) _local_remaining);
            signum = 1;
            if (bits[0] < 0) {
                // value is negative, clear the sign
                bits[0] &= 0x7F;
                signum = -1;
            }
            value = new BigInteger(signum, bits);
        } else {
            signum = 0;
            value = BigInteger.ZERO;
        }
        // Ion stores exponent, BigDecimal uses the negation "scale"
        int scale = -exponent;
        if (value.signum() == 0 && signum == -1) {
            assert value.equals(BigInteger.ZERO);
            bd = Decimal.negativeZero(scale, mathContext);
        } else {
            bd = Decimal.valueOf(value, scale, mathContext);
        }
        _local_remaining = save_limit;
    }
    return bd;
}
Also used : Decimal(com.amazon.ion.Decimal) BigDecimal(java.math.BigDecimal) BigInteger(java.math.BigInteger) MathContext(java.math.MathContext) SavePoint(com.amazon.ion.impl.UnifiedSavePointManagerX.SavePoint)

Example 2 with Decimal

use of com.amazon.ion.Decimal in project ion-java by amzn.

the class IonReaderBinarySystemX method load_scalar_value.

private final void load_scalar_value() throws IOException {
    // make sure we're trying to load a scalar value here
    switch(_value_type) {
        case NULL:
        case BOOL:
        case INT:
        case FLOAT:
        case DECIMAL:
        case TIMESTAMP:
        case SYMBOL:
        case STRING:
            break;
        default:
            return;
    }
    // well as when we encounter a null of any other type
    if (_value_is_null) {
        _v.setValueToNull(_value_type);
        _v.setAuthoritativeType(AS_TYPE.null_value);
        return;
    }
    switch(_value_type) {
        default:
            return;
        case BOOL:
            _v.setValue(_value_is_true);
            _v.setAuthoritativeType(AS_TYPE.boolean_value);
            break;
        case INT:
            boolean is_negative = _value_tid == _Private_IonConstants.tidNegInt;
            if (_value_len == 0) {
                if (is_negative) {
                    throwIllegalNegativeZeroException();
                }
                int v = 0;
                _v.setValue(v);
                _v.setAuthoritativeType(AS_TYPE.int_value);
            } else if (_value_len <= MAX_BINARY_LENGTH_LONG) {
                long v = readULong((int) _value_len);
                if (v < 0) {
                    // we probably can't fit this magnitude properly into a Java long
                    int signum = !is_negative ? 1 : -1;
                    BigInteger big = IonBinary.unsignedLongToBigInteger(signum, v);
                    _v.setValue(big);
                    // boundary condition
                    if (big.compareTo(MIN_LONG_VALUE) < 0 || big.compareTo(MAX_LONG_VALUE) > 0) {
                        _v.setAuthoritativeType(AS_TYPE.bigInteger_value);
                    } else {
                        // fits in long
                        // keep the BigInteger value set in case the user wants to resurrect it as such
                        _v.addValue(big.longValue());
                        _v.setAuthoritativeType(AS_TYPE.long_value);
                    }
                } else {
                    if (is_negative) {
                        if (v == 0) {
                            throwIllegalNegativeZeroException();
                        }
                        v = -v;
                    }
                    if (v < Integer.MIN_VALUE || v > Integer.MAX_VALUE) {
                        _v.setValue(v);
                        _v.setAuthoritativeType(AS_TYPE.long_value);
                    } else {
                        _v.setValue((int) v);
                        _v.setAuthoritativeType(AS_TYPE.int_value);
                    }
                }
            } else {
                BigInteger v = readBigInteger((int) _value_len, is_negative);
                _v.setValue(v);
                _v.setAuthoritativeType(AS_TYPE.bigInteger_value);
            }
            break;
        case FLOAT:
            double d;
            if (_value_len == 0) {
                d = 0.0;
            } else {
                d = readFloat((int) _value_len);
            }
            _v.setValue(d);
            _v.setAuthoritativeType(AS_TYPE.double_value);
            break;
        case DECIMAL:
            Decimal dec = readDecimal((int) _value_len);
            _v.setValue(dec);
            _v.setAuthoritativeType(AS_TYPE.decimal_value);
            break;
        case TIMESTAMP:
            // TODO: it looks like a 0 length return a null timestamp - is that right?
            Timestamp t = readTimestamp((int) _value_len);
            _v.setValue(t);
            _v.setAuthoritativeType(AS_TYPE.timestamp_value);
            break;
        case SYMBOL:
            long sid = readULong((int) _value_len);
            if (sid < 0 || sid > Integer.MAX_VALUE) {
                String message = "symbol id [" + sid + "] out of range " + "(1-" + Integer.MAX_VALUE + ")";
                throwErrorAt(message);
            }
            // TODO: is treating this as an int too misleading?
            _v.setValue((int) sid);
            _v.setAuthoritativeType(AS_TYPE.int_value);
            break;
        case STRING:
            String s = readString((int) _value_len);
            _v.setValue(s);
            _v.setAuthoritativeType(AS_TYPE.string_value);
            break;
    }
    _state = State.S_AFTER_VALUE;
}
Also used : Decimal(com.amazon.ion.Decimal) BigDecimal(java.math.BigDecimal) BigInteger(java.math.BigInteger) Timestamp(com.amazon.ion.Timestamp)

Example 3 with Decimal

use of com.amazon.ion.Decimal in project ion-java by amzn.

the class IonDecimalLite method hashCode.

@Override
int hashCode(SymbolTableProvider symbolTableProvider) {
    int result = HASH_SIGNATURE;
    // strict equality checks between two IonDecimals.
    if (!isNullValue()) {
        Decimal dec = decimalValue();
        result ^= dec.hashCode();
        if (dec.isNegativeZero()) {
            result ^= NEGATIVE_ZERO_HASH_SIGNATURE;
        }
    }
    return hashTypeAnnotations(result, symbolTableProvider);
}
Also used : IonDecimal(com.amazon.ion.IonDecimal) BigDecimal(java.math.BigDecimal) Decimal(com.amazon.ion.Decimal)

Example 4 with Decimal

use of com.amazon.ion.Decimal in project ion-java by amzn.

the class ReaderTest method testReadingFloatAsBigDecimal.

/**
 * This isn't allowed by the documentation, but it's allowed by the text
 * and binary readers.  Not allowed by the tree reader.
 *
 * We need to specify the conversion too, its non-trivial: does 0e0
 * convert to 0d0 or 0.0?  The latter is happening at this writing, but
 * it's not what one would expect.
 */
@Test
@Ignore
public // TODO amzn/ion-java/issues/56
void testReadingFloatAsBigDecimal() {
    BigDecimal actualBd = readBigDecimal("null.float");
    assertEquals(in.isNullValue(), actualBd == null);
    Decimal actualDec = readDecimal("null.decimal");
    assertEquals(in.isNullValue(), actualDec == null);
    assertEquals(actualBd, actualDec);
    // Note that one can't represent Long.MAX_VALUE as a double, there's
    // not enough bits in the mantissa!
    assertEquals(readBigDecimal("-0e0"), readDecimal("-0."));
    assertEquals(readBigDecimal("0e0"), readDecimal("0."));
    assertEquals(readBigDecimal("9223372036854776000e0"), readDecimal("9223372036854776000."));
    assertEquals(readBigDecimal("9223372036854776000e12"), readDecimal("9223372036854776000d12"));
    assertEquals(readBigDecimal("2e24"), readDecimal("2000000000000000000000000."));
}
Also used : Decimal(com.amazon.ion.Decimal) BigDecimal(java.math.BigDecimal) BigDecimal(java.math.BigDecimal) Ignore(org.junit.Ignore) Test(org.junit.Test) BinaryTest(com.amazon.ion.BinaryTest)

Example 5 with Decimal

use of com.amazon.ion.Decimal in project ion-java by amzn.

the class _Private_IonTextAppender method printDecimal.

public void printDecimal(_Private_IonTextWriterBuilder _options, BigDecimal value) throws IOException {
    if (value == null) {
        appendAscii("null.decimal");
        return;
    }
    BigInteger unscaled = value.unscaledValue();
    int signum = value.signum();
    if (signum < 0) {
        appendAscii('-');
        unscaled = unscaled.negate();
    } else if (value instanceof Decimal && ((Decimal) value).isNegativeZero()) {
        // for the various forms of negative zero we have to
        // write the sign ourselves, since neither BigInteger
        // nor BigDecimal recognize negative zero, but Ion does.
        appendAscii('-');
    }
    final String unscaledText = unscaled.toString();
    final int significantDigits = unscaledText.length();
    final int scale = value.scale();
    final int exponent = -scale;
    if (_options._decimal_as_float) {
        appendAscii(unscaledText);
        appendAscii('e');
        appendAscii(Integer.toString(exponent));
    } else if (exponent == 0) {
        appendAscii(unscaledText);
        appendAscii('.');
    } else if (exponent < 0) {
        // Avoid printing small negative exponents using a heuristic
        // adapted from http://speleotrove.com/decimal/daconvs.html
        final int adjustedExponent = significantDigits - 1 - scale;
        if (adjustedExponent >= 0) {
            int wholeDigits = significantDigits - scale;
            appendAscii(unscaledText, 0, wholeDigits);
            appendAscii('.');
            appendAscii(unscaledText, wholeDigits, significantDigits);
        } else if (adjustedExponent >= -6) {
            appendAscii("0.");
            appendAscii("00000", 0, scale - significantDigits);
            appendAscii(unscaledText);
        } else {
            appendAscii(unscaledText);
            appendAscii("d-");
            appendAscii(Integer.toString(scale));
        }
    } else // (exponent > 0)
    {
        // We cannot move the decimal point to the right, adding
        // rightmost zeros, because that would alter the precision.
        appendAscii(unscaledText);
        appendAscii('d');
        appendAscii(Integer.toString(exponent));
    }
}
Also used : Decimal(com.amazon.ion.Decimal) BigDecimal(java.math.BigDecimal) BigInteger(java.math.BigInteger)

Aggregations

Decimal (com.amazon.ion.Decimal)6 BigDecimal (java.math.BigDecimal)5 BigInteger (java.math.BigInteger)4 Timestamp (com.amazon.ion.Timestamp)2 BinaryTest (com.amazon.ion.BinaryTest)1 IonDecimal (com.amazon.ion.IonDecimal)1 IonType (com.amazon.ion.IonType)1 SymbolToken (com.amazon.ion.SymbolToken)1 SavePoint (com.amazon.ion.impl.UnifiedSavePointManagerX.SavePoint)1 MathContext (java.math.MathContext)1 Ignore (org.junit.Ignore)1 Test (org.junit.Test)1