融创白象街商铺:信息: 精度和在浮点计算精度

来源:百度文库 编辑:九乡新闻网 时间:2024/05/02 06:23:04

信息: 精度和在浮点计算精度

    很多情况下在哪个精度舍入,和浮点计算的准确性可以处理以生成对程序员令人惊讶的结果。有四个应遵循的一般规则:
    1. 在计算涉及单引号和双引号的精度,结果不通常会比单精度任何更准确。是否需要双精度一定包括常量,这一计算中的所有搜索条件在 $ 双精度中指定的。
    2. 永远不会假定计算机中准确地表示一个简单的数值。最浮点值不能精确地表示为一个有限的二进制值。例如,.1 是.0001100110011...(它重复永远) 的二进制中以便它不能使用二进制算术,其中包括所有 pc 的计算机上完成准确度来表示。
    3. 永远不会认为结果精确到在最后一个小数位。 总是有小"true"应答和 $ 任何浮动的点处理单位的有限的精度与计算内容之间的差异。
    4. 永远不会比较两个浮点值,以查看它们是否相等或不等。这是一个 corollary 规则 3。那里几乎总是将小"应该"是相等的数字之间的差异。而是,始终检查数字是否几乎相等。也就检查以确定它们之间的时差是否非常小或无关紧要。

    更多信息 一般情况下,上面所述,规则将应用于包括 C 和 c + +,组装器的所有语言。下面的示例演示一些使用 FORTRAN PowerStation 规则。所有这些示...

    一般情况下,上面所述,规则将应用于包括 C 和 c + +,组装器的所有语言。下面的示例演示一些使用 FORTRAN PowerStation 规则。所有这些示例是在不使用的最后一个写入 C.中除外的任何选项的情况下用 FORTRAN PowerStation 32 编译

    请参阅为数字的常量和文章 36068  (http://support.microsoft.com/kb/36068/EN-US/ ) 浮点值的内部表示方式的说明的说明提供与 Microsoft FORTRAN 在 FORTRAN manual(s)。 回到顶端

    示例 1

    第一个示例演示了两件事情:

    • FORTRAN 常量是默认情况下的单精度 (C 常量是默认情况下的双精度)。
    • 包含任何单精度条款计算不的计算其中的所有搜索条件的是单精度比更加准确。
    正在初始化与 1.1 (单精度常数),y 之后为单精度变量为不准确。
       x = 1.100000000000000  y = 1.100000023841858    
    的乘积由一个准确的双精度值的单精度值是作为将两个单精度值相乘几乎错误。这两个计算有数千次尽可能多地错误作为将两个双精度值相乘。
       true = 1.320000000000000 (multiplying 2 double precision values)    y    = 1.320000052452087 (multiplying a double and a single)    z    = 1.320000081062318 (multiplying 2 single precision values)    

    示例代码

    C Compile options: none    real*8 x,y,z    x = 1.1D0    y = 1.1    print *, 'x =',x, 'y =', y    y = 1.2 * x    z = 1.2 * 1.1    print *, x, y, z    end    

    示例 2

    示例 2 使用二次公式。它说明不完美,甚至双精度的计算,和的计算结果应该进行测试,它之前依赖小错误如果可以有严重的结果。平方根函数示例 2 中输入才非常略有负,但它仍然无效。如果双精度计算没有微小错误,结果将是:
       Root =   -1.1500000000    
    反而,它会生成以下错误: 运行时错误 M6201: 数学
    -sqrt: 域错误 回到顶端

    示例代码

    C Compile options: none    real*8 a,b,c,x,y    a=1.0D0    b=2.3D0    c=1.322D0    x = b**2    y = 4*a*c    print *,x,y,x-y    print "(' Root =',F16.10)",(-b+dsqrt(x-y))/(2*a)    end    
    回到顶端

    示例 3

    示例 3 说明由于要优化,即使未启用优化发生,值可能会暂时保留较高的精度比预期,以及它是非常 unwise 来测试相等的两个点的浮点值。

    此的示例在两个值是相等和不相等。在第一个 IF,Z 的值仍在协处理器的堆栈上,并具有相同的精度为 Y。因此 X 不等于 Y,第一条消息打印出来。第二个 IF 次 Z 不得不从内存加载,因此有相同的精度和为 X,值和第二个消息也会打印。 回到顶端

    示例代码

    C Compile options: none    real*8 y    y=27.1024D0    x=27.1024    z=y    if (x.ne.z) then    print *,'X does not equal Z'    end if    if (x.eq.z) then    print *,'X equals Z'    end if    end    
    回到顶端

    示例 4

    示例代码 4 的第一部分计算最小的可能接近于 1.0 的两个数差值。通过将有一个位添加到 1.0 的二进制表示形式执行此操作。
       x   = 1.00000000000000000  (one bit more than 1.0)    y   = 1.00000000000000000  (exactly 1.0)    x-y =  .00000000000000022  (smallest possible difference)    
    某些版本的 FORTRAN 舍入数字时显示它们,以便在固有数字不精确性不是那么明显。这是为什么 x 和 y 具有相同显示时的外观。

    第二部分的示例代码 4 计算最小的可能接近于 10.0 的两个数差值。再次,这一点通过将有一个位添加到 10.0 的二进制表示形式。请注意附近 10 的数字之差大于 1 附近的时差。此示例演示一般原则的越大绝对值的一个数字越小精确地它可以存储在给定的位数。
       x   = 10.00000000000000000  (one bit more than 10.0)    y   = 10.00000000000000000  (exactly 10.0)    x-y =   .00000000000000178    
    这些数字的二进制表示形式也会显示以显示它们是否不同只有一位。
       x = 4024000000000001 Hex    y = 4024000000000000 Hex    
    是最后一部分的示例代码 4 显示了简单非重复的十进制值通常可以在中表示的二进制文件只能由一个重复的分数。在此例 x = 1.05,这要求在尾数中重复的因子 CCCCCCCC....(Hex)。在 FORTRAN 中, 最后一位"C"会自动舍入,以"D"以便维持最高可能的准确性:
       x = 3FF0CCCCCCCCCCCD (Hex representation of 1.05D0)    
    偶数后舍入,结果不完全准确。有一些错误后最小有效位我们可以看到通过删除第一个数字。
       x-1 = .05000000000000004    

    示例代码

    C Compile options: none    IMPLICIT real*8 (A-Z)    integer*4 i(2)    real*8 x,y    equivalence (i(1),x)    x=1.    y=x    i(1)=i(1)+1    print "(1x,'x  =',F20.17,'  y=',f20.17)", x,y    print "(1x,'x-y=',F20.17)", x-y    print *    x=10.    y=x    i(1)=i(1)+1    print "(1x,'x  =',F20.17,'  y=',f20.17)", x,y    print "(1x,'x-y=',F20.17)", x-y    print *    print "(1x,'x  =',Z16,' Hex  y=',Z16,' Hex')", x,y    print *    x=1.05D0    print "(1x,'x  =',F20.17)", x    print "(1x,'x  =',Z16,' Hex')", x    x=x-1    print "(1x,'x-1=',F20.17)", x    print *    end    
    回到顶端

    示例 5

    在 C,浮动常量都是双精度数,默认情况下。使用"f"表示为"89.95f"中的浮点值。
       /* Compile options needed: none    */    #include     void main()    {    float floatvar;    double doublevar;    /* Print double constant. */    printf("89.95 = %f\n", 89.95);      // 89.95 = 89.950000    /* Printf float constant */    printf("89.95 = %f\n", 89.95F);     // 89.95 = 89.949997    /*** Use double constant. ***/    floatvar = 89.95;    doublevar = 89.95;    printf("89.95 = %f\n", floatvar);   // 89.95 = 89.949997    printf("89.95 = %lf\n", doublevar); // 89.95 = 89.950000    /*** Use float constant. ***/    floatvar = 89.95f;    doublevar = 89.95f;    printf("89.95 = %f\n", floatvar);   // 89.95 = 89.949997    printf("89.95 = %lf\n", doublevar); // 89.95 = 89.949997    }