首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中浮点类型的转换和计算

Java中浮点类型的转换和计算
EN

Stack Overflow用户
提问于 2015-09-15 20:49:23
回答 4查看 130关注 0票数 1

我试图在Java中更多地了解浮点数、双小数和双小数。我想知道浮点数在每种类型中是如何表示的,比如ex。浮点数使用2^,大小数使用10^加号(32位)和非缩放值(任意精度).

我把所有三种类型的简单计算组合在一起,并对每一种类型进行对话,结果是相当混乱的。我希望得到一些提示,说明为什么惟一正确的表示形式是用于浮点,以及为什么当转换为Double和BigDecimal时会出现不精确。它与二进制表示转换有关吗?总之,这里是代码及其输出:

代码语言:javascript
复制
    // Float - 32b
    float a = 3.14f;
    float b = 3.100004f;
    float abAsAFloat = a + b;
    double abAsADouble = a + b;
    BigDecimal abAsABigDecimal = new BigDecimal(a + b);

    System.out.println("a + b as a float: " + abAsAFloat);
    System.out.println("a + b as a double: " + abAsADouble);
    System.out.println("a + b as a BigDecimal: " + abAsABigDecimal);

    // Double - 64b
    double c = 3.14;
    double d = 3.100004;

    double cdAsADouble = c + d;
    BigDecimal cdAsABigDecimal = new BigDecimal(c + d);

    System.out.println("c + d as a double: " + cdAsADouble);
    System.out.println("c + d as a BigDecimal: " + cdAsABigDecimal);

    // BigDecimal, arbitrary-precision, signBit*unscaledValue × 10^-scale
    BigDecimal e = new BigDecimal(3.14);
    BigDecimal f = new BigDecimal(3.100004);

    BigDecimal efAsABigDecimal = e.add(f);

    System.out.println("e + f: " + efAsABigDecimal);

    // Drawbacks. speed, memory, native value equality, no overloads for +/- et al

A+b作为浮点数: 6.240004 A+b作为双倍: 6.240004062652588 A+b作为BigDecimal: 6.240004062652587890625 C+d作为双倍: 6.240004000000001 C++d作为一个6.2400040000000007722746886429376900196075439453125 :BigDecimal E+ f: 6.240004000000000328185478792875073850154876708984375

EN

回答 4

Stack Overflow用户

发布于 2015-09-15 20:56:40

对于这种特殊情况,float看起来可能是正确的,但对于其他值来说,它同样是错误的。请注意,当floatdouble转换为字符串时,只需要打印足够多的数字才能获得该类型的正确值;这意味着float可以打印“正确的答案”,即使表示形式隐藏了与double一样多的舍入错误。

BigDecimal的问题在于您没有正确地使用它:您应该编写new BigDecimal("3.14")而不是new BigDecimal(3.14),这允许doubleBigDecimal有机会“修复它”之前“把它搞砸”。

对于表示的细节,格式化用有用的图表作了详尽的解释,但简短的解释是,floatdouble将数字表示为+/- 1* 1. * 2^,其中float存储尾数22位,指数存储8位,double分别使用52位和11位。

票数 0
EN

Stack Overflow用户

发布于 2015-09-15 20:58:37

你无意中混合了类型。例如:

代码语言:javascript
复制
BigDecimal e = new BigDecimal(3.14);
BigDecimal f = new BigDecimal(3.100004);

在这种情况下,您提供双倍作为输入,因此e和f将有双剩余。相反,请使用以下命令:

代码语言:javascript
复制
BigDecimal e = new BigDecimal("3.14");
BigDecimal f = new BigDecimal("3.100004");

浮点输出似乎是最精确的,因为Java“知道”浮点数的精度有限,所以它不会打印15位数字。

票数 0
EN

Stack Overflow用户

发布于 2015-09-15 21:01:11

当您转换为doubleBigDecimal时,它将转换为最接近可表示的值。当您转换到BigDecimal时,您实际上首先要转换为double,因为没有直接从float进行的转换。

通常,您想要使用double转换为BigDecimal,这个方法假设一定程度的舍入,以匹配如果打印它的话,它看起来会是什么样子。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32595351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档