org.ttzero.excel.entity.e3.RKValue Maven / Gradle / Ivy
/*
* Copyright (c) 2019-2020, [email protected] All Rights Reserved.
*
* 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.
*/
package org.ttzero.excel.entity.e3;
/**
* 2.5.5 RK Values
*
* An RK value is an encoded integer or floating-point value.
* RK values have a size of 4 bytes and are used to decrease
* file size for floating-point values.
*
* If bit 1 is cleared, the encoded value represents the 30 most
* significant bits of an IEEE 754 floating-point value (64-bit
* double precision). The 34 least significant bits must be set
* to zero. If bit 1 is set, the encoded value represents a signed
* 30-bit integer value. To get the correct integer, the encoded
* value has to be shifted right arithmetically by 2 bits. If bit 0
* is set, the decoded value (both integer and floating-point) must
* be divided by 100 to get the final result.
*
* @author guanquan.wang at 2019-01-31 09:40
*/
public class RKValue {
// part of integer
private int v1;
// part of float
private double v2;
// true if value is Floating-point
private boolean floating;
public RKValue() { }
public RKValue(int value) {
initWith(value);
}
public void initWith(int value) {
Option option = Option.of(value);
boolean div100 = option.isOn(0);
boolean signedInteger = option.isOn(1);
this.floating = !signedInteger
|| div100 && (option.isOn(2) || option.isOn(3));
int t = option.range(2, 30);
// Signed integer value
if (signedInteger) {
if (div100) {
double d = t / 100.0;
v1 = t / 100;
v2 = d - v1;
} else {
v1 = t;
}
// Floating-point value
} else {
// the encoded value represents the 30 most significant bits of an IEEE 754 floating-point value (64-bit
// double precision). The 34 least significant bits must be set to zero
double dv = Block.IEEE754DoublePrecision((long) t << 34);
if (div100) {
dv /= 100.0;
}
v1 = (int) dv;
v2 = dv - v1;
}
}
public static RKValue valueOf(int value) {
return new RKValue(value);
}
/**
* Check value type
*
* @return true if RK Value is Floating-point
*/
public boolean isFloat() {
return floating;
}
/**
* Part of integer
*
* @return v1
*/
public int value1() {
return v1;
}
/**
* Part of float-point
*
* @return v2
*/
public double value2() {
return v2;
}
public double value() {
return v1 + v2;
}
@Override
public String toString() {
return floating ? String.valueOf(v1 + v2) : String.valueOf(v1);
}
}