BigDecimal bigDecimal = new BigDecimal("44e016912630333") 为啥报错java.lang.NumberFormatException

颖辉小居 发布于 2020/09/02 14:21
阅读 1K+
收藏 1

如题:BigDecimal bigDecimal = new BigDecimal("44e016912630333") 为啥报错java.lang.NumberFormatException

44e016912630333 就是个数字啊
加载中
1
tcxu
tcxu

楼主的字符串代表的是 16 进制的数, 因为有字符 e。
因此,先要将其解析成 10 进制, 并生成一个 BigInteger 对象。
以这个对象为参数,方可得出一个 BigDecimal 对象.

BigDecimal bigDecimal = new BigDecimal(new BigInteger("44e016912630333",16));

注意,楼主的做法:用 Double.valueOf("44e016912630333"); 
想得都一个双精度的包装类对象。此法不妥。

import java.math.*;
import java.lang.Double;
public class X{
public static void main(String args[]){
	
	BigDecimal bigDecimal = new BigDecimal(new BigInteger("44e016912630333",16));
	Double d = Double.valueOf("44e016912630333"); 
	System.out.println("得到 BigDecimal 对象:" + bigDecimal);
	System.out.println("得到 Double 对象:"+ d);
	}
}

DOS 输出:

D:\java\test\OS_China>javac X.java

D:\java\test\OS_China>java X
得到 BigDecimal 对象:310186975126815539
得到 Double 对象:Infinity

D:\java\test\OS_China>

 

颖辉小居
颖辉小居
Double.valueOf("44e016912630333"); 得到Infinity确实超过最大值范围了。但是您说的因为字符串有e就是16进制。我认为不是这样的,比如缩短e后面的指数 new BigDecimal("44e1"); 最终结果 4.4E+2 与 Float.valueOf("44e1"); 的结果是相等的都表示 44 x 10^1 = 440。原字符串本意不是16进制。
1
巴拉迪维
巴拉迪维
44e016912630333

明明是个字符串,为什么要说这是数字呢?如果是数字,是多少?

颖辉小居
颖辉小居
Double.valueOf("44e016912630333"); 这个就可以
巴拉迪维
巴拉迪维
回复 @颖辉小居 : 那最后应该加上 d 或者 f 才对吧?
颖辉小居
颖辉小居
科学计数法 44 x 10的 016912630333次幂
1
Kit_lee
Kit_lee

范围超了,不支持,幂数减少一些就支持了

1
今年是我咯

重新回答下,bigdecimal new的时候,遍历字符串,遇到e的时候会按科学计数法去解析

} else if ((c == 'e') || (c == 'E')) {
    exp = parseExp(in, offset, len);
    // Next test is required for backwards compatibility
    if ((int) exp != exp) // overflow
        throw new NumberFormatException();
    break; // [saves a test]

解析的时候会去判断后面的字符长度大于10,且转换为10进制不为0的长度,如果超过10的话,会报错。

 

// skip leading zeros in the exponent
while (len > 10 && (c=='0' || (Character.digit(c, 10) == 0))) {
    offset++;
    c = in[offset];
    len--;
}
if (len > 10) // too many nonzero exponent digits
    throw new NumberFormatException();

所以是看你e后面的字符的。    

像这种就正确

BigDecimal bigDecimal2 = new BigDecimal("44e00000000000000000003330");

4.4E+3331

1
k
kzcm

如果是16 进制的数字,直接可以以数字的构造去构造,如果是字符串 带 'e',报错是正常的

BigDecimal bigDecimal = new BigDecimal(0x44e016912630333L);

 

0
tonglingbaoyu
tonglingbaoyu

44e016912630333  这是指数形式的数字

还是16jin'zhi

0
方塘半亩
方塘半亩

这个应该是超范围了吧.....44的 16912630333 次幂.......加个d吧

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部