【问题标题】:Very small simple precision and double precision float numbers representation非常小的简单精度和双精度浮点数表示
【发布时间】:2015-06-19 22:50:54
【问题描述】:

当我试图计算一些非常小的简单精度和双精度浮点数时,我遇到了一些问题。

看看下面的代码示例:

public class FloatingLimits {

    public static void doSimpleFloatingLimitDemo() {
        float firstValue = 1.56F;
        float newValue = 1.0F / ((float)Math.pow(2.0D, 150));

        double doubleFirst = 2.56;
        double doubleNew = 1.0F /Math.pow(2.0D, 150);
        double doubleThird = 1.0F/Math.pow(2.0D, 589);
        double doubleFourth = 1.0F/Math.pow(2.0, 1589);

        System.out.println("float first value =" + firstValue);
        System.out.println("float new value =" + newValue);

        System.out.println("double first value =" + doubleFirst);
        System.out.println("double new value =" + doubleNew);
        System.out.println("double third value =" + doubleThird);
        System.out.println("double fourth value =" + doubleFourth);

    }


    public static void main(String[] args) {
        doSimpleFloatingLimitDemo();

    }
}

它产生以下结果:

因此存在表示问题或显示问题!这与数字精度有关吗?我无法用简单的浮点精度类型(32 位)表示的非常小的数字可以用双浮点精度数(64 位)表示,但双浮点也显示了限制。那么对于非常小的数字,这个限制是多少?是否有使用浮点数和双精度数的解决方法,或者我是否必须使用 BigDecimal 来解决它。如果我必须使用 BigDecimals,BigDecimal 表示是否也有一定的限制?

【问题讨论】:

    标签: java floating-point numbers representation


    【解决方案1】:

    如果你看Double.MAX_VALUE

    保持双精度类型的最大正有限值的常数,(2-2-52).21023

    如果你运行:

    System.out.println(Math.pow(2.0, 1589));
    

    你会看到预期的结果:

    无限

    【讨论】:

    • 所以,这就是为什么它给我 0.0 作为结果。谢谢@assylias。 BigDecimal 是替代品吗?
    • @alainlompo 如果您需要那么大的数字,是的,或者 BigInteger 如果它们是整数。
    【解决方案2】:

    如果您需要以任意精度表示十进制数,您必须使用BigDecimal

    这是一个链接

    http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

    float 和 double 的内部二进制表示会引入错误。另一种可能性是使用intlong 将值乘以一个因子(10、100、1000 ...)并将它们视为非十进制值。

    【讨论】:

    • 谢谢。那么我可以使用双精度和浮点数走多远?还是我应该完全放弃它们以使用 BigDecimal 或您建议的乘法因子?谢谢
    • 如果不需要任意精度并且主要需要执行速度,您可以使用 float 和 double。
    • 好吧,我明白了,如果我要编写一个 3D 游戏,我会首先使用整数,除非我需要更精确的精度,否则我会使用浮点数或双精度数...... BigDecimal 可能不会适合这种情况...谢谢
    • 这个问题与floatdouble 是二进制浮点这一事实无关(实际上,2^-589 和 2^-1589 完全可以用二进制浮点表示只要它们适合可用范围),并且此答案中具有此效果的段落只是死记硬背。此外,答案暗示BigDecimal 不会引入错误。尝试用 BigDecimal 表示 1/3。
    • 在 3D 游戏中使用 double 可能还有另一个动机 - 它有效支持正弦和反正切等三角函数。
    猜你喜欢
    • 2018-02-23
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多