获取存储的实际数字

时间:2012-12-17 20:48:48

标签: java floating-point bigdecimal ieee-754

我有一个使用泰勒系列创建科学计算器的项目。此外,我正在分析ieee 754标准浮点系统的数字。

在我的计算器中,用户选择是否需要单精度或双精度:我使用float和double变量,  然后我分析了ieee 754规范之后的数字。

如果用户想要双精度,则分析如下:

double analyze=3.45
BigDecimal bd=new BigDecimal(analyze) 

给了我

3.45000000000000017763568394002504646778106689453125
  1. 这个号码是以二进制格式存储在个人电脑内存中的实际号码吗?

  2. 如果不是这样我可以获得存储数字的实际值吗?

  3. 为什么会这样呢?

    double analyze=0.5
    BigDecimal db=new BigBecimal(analyze)

  4. 仅打印0.5 - 为什么我会丢失有效数字?

    有人可以告诉我为什么会发生这种情况

            BigDecimal one=new BigDecimal(0.1);
            BigDecimal five=one.multiply(new BigDecimal(5)) ;
            System.out.println("5 times 0.1 is "+" "+ five);
    
            System.out.println("But the 0.5 in BigDecimal is " + " "+ new BigDecimal(0.5));
    

    通过运行这个你得到                5次0.1是0.5000000000000000277555756156289135105907917022705078125                 但是BigDecimal中的0.5是0.5

4 个答案:

答案 0 :(得分:3)

  

1.i想问你这个号码是以二进制格式存储在pc内存中的实际号码吗?

  

2.如果我没有任何方式可以获得存储数字的实际值

嗯,是的,所以没问题。

  
      
  1. 它仅打印我 - > 0.5为什么我会丢失有意义的数字?
  2.   

你没有; 0.5是以二进制格式存储的确切数字。

答案 1 :(得分:3)

  1. 是,3.45000000000000017763568394002504646778106689453125是将数字“3.45”转换为普通双重格式时存储在double中的实际值。

  2. 这才是真正的价值。

  3. 您没有显示打印0.5的方法。我记得,在可能的情况下,Java中常见的显示机制之一就是根据需要打印尽可能多的数字来准确表示值。它不会打印尾随零,因为它们是多余的。

  4. 您可能想知道“好吧,如果只打印.5,我怎么知道这个数字是.5000000000而不是.5000000001或类似的东西?”答案是,如果数字不同于.5,更多将打印数字,因为显示机制被定义为这样做。所以你可以依赖“.5”意味着.5,仅此而已。

    如果这是一个学校项目,那么您可能不需要担心3.45表示的值略有不同。只需继续使用double中的值进行计算。

    另外,泰勒系列对于真正的计算器来说是一个糟糕的选择,因为它们被设计成在一个点附近准确,但你会想要一个在一个间隔内准确的系列。还有其他系列可以更好地传播错误,因此他们需要更少的术语才能获得准确的结果。如果它被建议作为学校项目的一部分,我只会使用泰勒系列。

答案 2 :(得分:1)

  1. 是。 BigDecimal(double)构造函数“将double转换为BigDecimal,它是double的二进制浮点值的精确十进制表示形式。” BigDecimal toString方法显示确切的值。

  2. N / A

  3. 0.5可以完全表示为double。 BigDecimal(0.5)结果具有未缩放的值5和比例1.它满足BigDecimal toString条件,无需指数即可显示。小数点后的位数等于刻度,1。

  4. 您的示例代码:

        BigDecimal one=new BigDecimal(0.1);
        BigDecimal five=one.multiply(new BigDecimal(5)) ;
    
    除非您正在探测双重表示,否则

    会出现使用BigDecimal双构造函数的问题。 0.1并不能完全表示为double,因此即使BigDecimal("0.1")完全正确,您的“one”也不完全为0.1。

    更一般地说,double的确切值始终为a/(2**b)形式,其中ab为整数,"**"表示取幂。 (a * 5**b)/(10**b)具有相同的值,并且可以表示为具有比例b的BigDecimal。

答案 3 :(得分:-2)

一般来说,float和double将完全代表十进制数字(除了两个和其他一些“甜点”的权力)。该数字以二进制形式存储在内部。您可以使用Double.doubleToRawLongBitsFloat.floatToRawIntBits访问内部代表。