第一个与相应的 long 相差 delta 的双精度数是多少?

2023-12-07

我想知道从 0d 向上的第一个双精度数,该双精度数偏离“相同值”的长整型某个增量,例如 1e-8。不过我在这里失败了。尽管我通常使用托管语言,但我正在尝试用 C 来执行此操作,以防万一。请帮忙。


#include <stdio.h>
#include <limits.h>
#define DELTA 1e-8

int main() {
    double d = 0; // checked, the literal is fine
    long i;
    for (i = 0L; i < LONG_MAX; i++) {
         d=i; // gcc does the cast right, i checked
         if (d-i > DELTA || d-i < -DELTA) {
              printf("%f", d);
              break;
         }
    }
}

我猜测问题在于 d-i 将 i 转换为 double,因此 d==i 然后差值始终为 0。我还能如何正确检测到这一点 - 我更喜欢有趣的 C 转换而不是比较字符串,这会永远。

ANSWER: 和我们预想的一模一样。根据标准 C/UNIX/POSIX 工具,2^53+1 = 9007199254740993 是第一个差异点。非常感谢 pax 的节目。我想数学又赢了。


Doubles in IEE-754 have a precision of 52 bits which means they can store numbers accurately up to (at least) 251.

If your longs are 32-bit, they will only have the (positive) range 0 .. 231 - 1 so there is no 32-bit long that cannot be represented exactly as a double. For a 64-bit long, it will be (roughly) 252 so I'd be starting around there, not at zero.

您可以使用以下程序来检测故障开始发生的位置。在早期版本中,我依赖于这样一个事实:连续加倍的数字的最后一位数字遵循序列 {2,4,8,6}。然而,我最终选择使用已知的可信工具(bc)用于检查整个数字,而不仅仅是最后一位数字。

Keep in mind that this may be affected by the actions of sprintf() rather than the real accuracy of doubles (I don't think so personally since it had no troubles with certain numbers up to 2143).

这是我写的测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    FILE *fin;
    double d = 3.0; // 2^n + 1 to avoid exact powers of 2.
    int i = 1;
    char ds[1000];
    char tst[1000];

    // Loop forever, rely on break to finish.

    while (1) {
        // Get C version of the double.

        sprintf (ds, "%.0f", d);

        // Get bc version of the double.

        sprintf (tst, "echo '2^%d - 1' | bc >tmpfile", i);
        system(tst);
        fin = fopen ("tmpfile", "r");
        fgets (tst, sizeof (tst), fin);
        fclose (fin);
        tst[strlen (tst) - 1] = '\0';

        // Check them.

        if (strcmp (ds, tst) != 0) {
            printf( "2^%d + 1 <-- bc failure\n", i);
            printf( "   got       [%s]\n", ds);
            printf( "   expected  [%s]\n", tst);
            break;
        }

        // Output for status then move to next.

        printf( "2^%d + 1 = %s\n", i, ds);
        d = (d - 1) * 2 + 1;  // Again, 2^n + 1.
        i++;
    }
}

这一直持续到:

2^49 + 1 = 562949953421313
2^50 + 1 = 1125899906842625
2^51 + 1 = 2251799813685249
2^52 + 1 = 4503599627370497
2^53 + 1 <-- bc failure
   got       [9007199254740992]
   expected  [9007199254740993]

这是roughly关于我预计它会失败的地方。

As an aside, I originally used numbers of the form 2n but that got me all the way up to:

2^136 = 87112285931760246646623899502532662132736
2^137 = 174224571863520493293247799005065324265472
2^138 = 348449143727040986586495598010130648530944
2^139 = 696898287454081973172991196020261297061888
2^140 = 1393796574908163946345982392040522594123776
2^141 = 2787593149816327892691964784081045188247552
2^142 = 5575186299632655785383929568162090376495104
2^143 <-- bc failure
   got       [11150372599265311570767859136324180752990210]
   expected  [11150372599265311570767859136324180752990208]

with the size of a double being 8 bytes (checked with sizeof). It turned out these numbers were of the binary form 1000...000, which can be represented for far longer with doubles. That's when I switched to using 2n + 1 to get a better bit pattern (one at the start and one at the end).


现在,要明确的是,most可靠的方法是检查每个数字,看看哪个数字首先失败,但这将需要相当长的运行时间。考虑到 IEEE-754 编码的知识,这种方法是最好的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第一个与相应的 long 相差 delta 的双精度数是多少? 的相关文章

  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • gcc,我可以将 offsetof() 与指向成员的模板化指针一起使用吗?

    下面的代码在这里 https ideone com XnxAyw https ideone com XnxAyw 我得到的编译器错误是 prog cpp In member function size t list base
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 石和磅的格式正确吗?

    我有一个图表 用于显示重量 以英石和磅 lbs 为单位 该图表由记录中的数据填充 对于权重 数据类型为 Double 记录数据是在运行时编辑的 我需要知道一种正确格式化输入数据的方法 为了更好地理解 首先看一下这些示例值 它们表示为石和磅
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐