【问题标题】:Grid step (difference between two adjacent machine-representable numbers网格步长(两个相邻机器可表示数字之间的差异
【发布时间】:2021-04-11 17:06:26
【问题描述】:

我写了这样一个代码来查找网格步长(两个相邻的机器可表示数之间的差,机器 epsilon 是大于一和一的最小机器可表示数之间的差)。为什么这个程序对于 x 的巨大值显示 1 以及如何修复它以显示正确答案?

#include <stdio.h>
int main(void)
{
    long double x,eps=1.0,a; 
    scanf("%Lg",&x);
    do
    {
        a=eps;
        eps/=2.0;
    }
    while( x+eps>x);
    printf("Grid step: %Le",(long double)a);
    return 0;
}

【问题讨论】:

  • 请不要标记 C 和 C++,除非询问两种不同语言之间的差异或交互。
  • 对不起。 c 和 c++ 是非常接近的语言,因为我写
  • 请选择一个保留并删除另一个标签。尽管这个问题根本不是关于 C 或 C++ 的;您可以添加浮点标签 [floating-point] 和 [ieee-754] 并删除语言标签(但在问题中提到正在使用 C 或 C++ 代码)。

标签: floating-point ieee-754


【解决方案1】:

浮点数表示为符号(+1 或 -1)s、指数 e 和数字 f具有固定基数的固定位数(称为有效数字)。以 b 为底,精度(位数)p,用符号 s 表示的数字,指数 e,和数字 f0, f-1, f-2 , f-3, f-4,… f 1−psbe •sum(fibi对于 -p

例如,底数为 2、精度为 4、符号 +1、指数 1 和有效位数 1.001,表示的数字为 +1•21•1.0012 = 2•1⅛ = 2¼ = 9/4 = 2.25。

给定范围内的任何可表示数,通过将有效数的最低位加 1 来获得下一个更大的可表示数。在上面的例子中,下一个更大的数字的有效数为 1.010,并且符号和指数相同,因此它将是 +1•21•1.0102 = 2•1¼ = 2½ = 10/4 = 2.5。

这意味着,如果一个数字x用指数e表示,那么它与下一个更大的可表示数字之间的差是beb1-p = be+1−p.

数字 1 用指数 0 表示,因为 1 = +1•b0•1.000…000b。所以 1 和下一个可表示的数之间的差是 b1−p。如果您的long double 格式的基数为 2,精度为 64 位(位),则此差异为 21−64 = 2−63,因此所谓“机器ε”的值应该是2-63

如果使用的是二进制格式,那么 2 用指数 1 表示,因此它与下一个可表示的数字之间的差是 be+1−p = 21+1−64 = 2−62。这些差异称为 ULP,即最低精度单位。

4 的 ULP 为 2-61,8 的 ULP 为 2-60,以此类推。对于 263,ULP 为 263−63 = 1。

当您输入 264 或更大的数字时,您的程序无法找到 ULP,因为 ULP 大于 1,但您的程序开始查找 1 并向下工作。

您可以通过从long double 格式中可能的最大 ULP 开始,或者根据x 的值将程序更改为向上或向下工作来修复它。

【讨论】:

  • 我该如何解决这个问题?你知道吗?
  • 我希望这个程序适用于任何值。但是现在这个程序在屏幕上给了我 1.0000... 当我写大值时
猜你喜欢
  • 1970-01-01
  • 2017-11-02
  • 2021-12-05
  • 2012-04-30
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-13
相关资源
最近更新 更多