我有一个十六进制格式的大数字(带小数点)String,我希望将它转换为BigDecimal.
示例值: 0xcc.ccdp+1600
在BigDecimal类中,我没有看到任何以十六进制格式表示数字的字符串作为输入并返回相应的函数BigDecimal.
有没有办法将大十六进制数转换String为BigDecimal?
我很惊讶,BigDecimal还没有支持这一点.我写了以下内容,我认为应该可行.它通过我的初步测试(用0xcc.ccdp+0,0xcc.ccdp+1,0xcc.ccdp+16,0xcc.ccdp+256,和你的0xcc.ccdp+1600,也有一些负指数,从-1下到-16),但它应该在生产代码在使用前更彻底地测试.
private final static BigInteger TWO = BigInteger.valueOf(2);
private final static BigDecimal MINUS_ONE = new BigDecimal(-1);
public static BigDecimal toBigDecimal(String hex) {
// handle leading sign
BigDecimal sign = null;
if (hex.startsWith("-")) {
hex = hex.substring(1);
sign = MINUS_ONE;
} else if (hex.startsWith("+")) {
hex = hex.substring(1);
}
// constant must start with 0x or 0X
if (!(hex.startsWith("0x") || hex.startsWith("0X"))) {
throw new IllegalArgumentException(
"not a hexadecimal floating point constant");
}
hex = hex.substring(2);
// ... and end in 'p' or 'P' and an exponent
int p = hex.indexOf("p");
if (p < 0) p = hex.indexOf("P");
if (p < 0) {
throw new IllegalArgumentException(
"not a hexadecimal floating point constant");
}
String mantissa = hex.substring(0, p);
String exponent = hex.substring(p+1);
// find the hexadecimal point, if any
int hexadecimalPoint = mantissa.indexOf(".");
int hexadecimalPlaces = 0;
if (hexadecimalPoint >= 0) {
hexadecimalPlaces = mantissa.length() - 1 - hexadecimalPoint;
mantissa = mantissa.substring(0, hexadecimalPoint) +
mantissa.substring(hexadecimalPoint + 1);
}
// reduce the exponent by 4 for every hexadecimal place
int binaryExponent = Integer.valueOf(exponent) - (hexadecimalPlaces * 4);
boolean positive = true;
if (binaryExponent < 0) {
binaryExponent = -binaryExponent;
positive = false;
}
BigDecimal base = new BigDecimal(new BigInteger(mantissa, 16));
BigDecimal factor = new BigDecimal(TWO.pow(binaryExponent));
BigDecimal value = positive? base.multiply(factor) : base.divide(factor);
if (sign != null) value = value.multiply(sign);
return value;
}
Run Code Online (Sandbox Code Playgroud)
我已经在MIT许可下在github上发布了这个.有单元测试,但只有一个非常小的集合.
如果您发现任何返回错误值的情况,请告诉我.
| 归档时间: |
|
| 查看次数: |
1857 次 |
| 最近记录: |