Description
Writes BigDecimal value.
License
Apache License
Parameter
Parameter | Description |
---|
val | Value. |
out | Data output. |
Exception
Parameter | Description |
---|
IOException | if failed to write value. |
Declaration
public static void writeBigDecimal(BigDecimal val, DataOutput out) throws IOException
Method Source Code
//package com.java2s;
/*/*from w w w. j a va2s. c o m*/
* Copyright 2019 The Hekate Project
*
* The Hekate Project 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.
*/
import java.io.DataOutput;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
public class Main {
private static final byte DECIMAL_ZERO = 1;
private static final byte DECIMAL_ONE = 2;
private static final byte DECIMAL_TEN = 3;
private static final byte DECIMAL_SMALL_UNSCALED = 4;
private static final byte DECIMAL_SMALL_SCALED = 5;
private static final byte DECIMAL_BIG = 6;
private static final int LONG_BITS = 63;
/**
* Writes {@link BigDecimal} value. The written value can be read via {@link #readBigDecimal(DataInput)}.
*
* @param val Value.
* @param out Data output.
*
* @throws IOException if failed to write value.
*/
public static void writeBigDecimal(BigDecimal val, DataOutput out) throws IOException {
if (val.compareTo(BigDecimal.ZERO) == 0) {
out.writeByte(DECIMAL_ZERO);
} else if (val.compareTo(BigDecimal.ONE) == 0) {
out.writeByte(DECIMAL_ONE);
} else if (val.compareTo(BigDecimal.TEN) == 0) {
out.writeByte(DECIMAL_TEN);
} else {
int scale = val.scale();
BigInteger unscaled = val.unscaledValue();
int bits = unscaled.bitLength();
if (bits <= LONG_BITS) {
if (scale == 0) {
out.writeByte(DECIMAL_SMALL_UNSCALED);
} else {
out.writeByte(DECIMAL_SMALL_SCALED);
writeVarIntUnsigned(scale, out);
}
writeVarLong(unscaled.longValue(), out);
} else {
byte[] bytes = unscaled.toByteArray();
out.writeByte(DECIMAL_BIG);
writeVarIntUnsigned(scale, out);
writeVarIntUnsigned(bytes.length, out);
out.write(bytes, 0, bytes.length);
}
}
}
/**
* Encodes a value using the variable-length encoding from <a href="http://code.google.com/apis/protocolbuffers/docs/encoding.html">
* Google Protocol Buffers</a>. Zig-zag is not used, so input must not be negative. If values can be negative, use {@link
* #writeVarInt(int, DataOutput)} instead. This method treats negative input as like a large unsigned value.
*
* @param value Value to encode (must be non-negative).
* @param out Data output.
*
* @throws IOException if failed to write value.
*/
// Code borrowed from 'stream-lib' (Apache 2.0 license) - see https://github.com/addthis/stream-lib
public static void writeVarIntUnsigned(int value, DataOutput out) throws IOException {
while ((value & 0xFFFFFF80) != 0L) {
out.writeByte((value & 0x7F) | 0x80);
value >>>= 7;
}
out.writeByte(value & 0x7F);
}
/**
* Encodes a value using the variable-length encoding from <a href="http://code.google.com/apis/protocolbuffers/docs/encoding.html">
* Google Protocol Buffers</a>. It uses zig-zag encoding to efficiently encode signed values. If values are known to be non-negative,
* {@link #writeVarLongUnsigned(long, DataOutput)} should be used.
*
* @param value Value to encode
* @param out Data output.
*
* @throws IOException if failed to write value.
*/
// Code borrowed from 'stream-lib' (Apache 2.0 license) - see https://github.com/addthis/stream-lib
public static void writeVarLong(long value, DataOutput out) throws IOException {
// Great trick from http://code.google.com/apis/protocolbuffers/docs/encoding.html#types
writeVarLongUnsigned(value << 1 ^ value >> LONG_BITS, out);
}
/**
* Encodes a value using the variable-length encoding from <a href="http://code.google.com/apis/protocolbuffers/docs/encoding.html">
* Google Protocol Buffers</a>. Zig-zag is not used, so input must not be negative. If values can be negative, use {@link
* #writeVarLong(long, DataOutput)} instead. This method treats negative input as like a large unsigned value.
*
* @param value Value to encode (must be non-negative).
* @param out Data output.
*
* @throws IOException if failed to write value.
*/
// Code borrowed from 'stream-lib' (Apache 2.0 license) - see https://github.com/addthis/stream-lib
public static void writeVarLongUnsigned(long value, DataOutput out) throws IOException {
while ((value & 0xFFFFFFFFFFFFFF80L) != 0L) {
out.writeByte(((int) value & 0x7F) | 0x80);
value >>>= 7;
}
out.writeByte((int) value & 0x7F);
}
}
Related
- tryToStoreAsIntegerBigDecimal(Object ob)
- tryToStoreAsRealBigDecimal(Object ob)
- unformattedFromBigDecimal(BigDecimal n)
- unformattedToBigDecimal(String str)
- valueOf(final BigDecimal value)
- writeBigDecimal(final OutputStream out, @Nullable final BigDecimal value)
- zeroOrMore(BigDecimal decimal)