第一个与相应的 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 的双精度数是多少? 的相关文章

  • 结构体如何存储在内存中?

    我有一个struct iof header在我的代码中 我确定它的宽度是 24 字节 我执行 sizeof iof header 它返回 32 字节宽 问题1为什么是 32 字节宽而不是 24 字节宽 问题2包括其成员在内 结构体如何存储在
  • .NET 单点登录

    我一直在尝试使用 C 为 NET Web 应用程序实现 WEB SSO 服务提供程序插件 我将使用 shibboleth 身份提供商 我已经使用 OpenSAML 库为 java 应用程序实现了相同的功能 我想知道在 NET 应用程序中使用
  • fopen_s 怎么会比 fopen 更安全呢?

    我正在处理遗留代码Windows平台 当我编译代码时VS2013 它给出以下警告 错误 C4996 fopen 该函数或变量可能不安全 考虑使用fopen s反而 要禁用弃用 请使用 CRT SECURE NO WARNINGS 详情请参见
  • 使用 C# 将多个音频样本混合到单个文件中

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个能够创建音频文件 mp3 或 wav 的库 NAudio http www codeple
  • 为什么子函数不销毁GtkWindow?

    这是我的代码 void window first void enter window2 GtkWidget w gpointer data void quit GtkWidget w gpointer data void quit int
  • 将 dataGridView 中选定的行作为对象检索

    我有一堂这样的课 public partial class AdressBokPerson public long Session get set public string F rnamn get set public string Ef
  • opencv中如何去除二值图像噪声?

    将图像转换为二值图像 黑白 后如果有任何噪音怎么办 我消除了那些不需要的噪音 您可以看到下图的黑色区域内有一些白噪声 我该如何去除噪声 使用opencv http img857 imageshack us img857 999 blackn
  • 如何减少 MinGW g++ 编译器生成的可执行文件的大小?

    我有一个简单的 Hello world C 程序 在 Win XP 下由 MinGW g 编译器编译为 500kB 可执行文件 有人说这是由于iostream的库和静态链接libstdc dll Using s链接器选项有点帮助 减少了 5
  • 控制台应用程序中使用 Unicode 字符的 _tprintf

    我正在从 Unicode 构建的控制台应用程序 使用 C 和 Visual Studio 2008 执行这个简单的输出 此代码旨在在 Windows 上运行 tprintf L Some sample string n 一切正常 但是如果我
  • 如何自定义 Google 测试失败消息?

    我编写了一个如下所示的 Google 测试 它将一些计算值与 CSV 文件中预期存储的值进行比较 class SampleTest public testing Test public void setupFile const std st
  • 如何将STL容器数据转储到gdb中?

    我无法在 gdb 中转储 STL 无序映射容器值 变量类型是 std unordered map var 我的 gdb 版本 7 7 1 GDB配置 configure host x86 64 linux gnu target x86 64
  • 您对“大规模 C++ 软件设计”的看法 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 正在阅读亚马逊评论 https rads stackoverflow com amzn click com 0201633620 and ACC
  • 更改 Xamarin.Forms 应用中顶部栏和底部栏(ControlsBar、StatusBar)的颜色

    无论如何 即使后面需要特定于平台的代码 也可以更改顶部栏 蓝色的 和底部栏 黑色的 的颜色吗 我希望添加对浅色和深色模式的支持 因此我希望能够在运行时更改它 有可能的 Android Using Window SetStatusBarCol
  • C#:自定义转换为值类型

    是否可以将自定义类转换为值类型 这是一个例子 var x new Foo var y int x Does not compile 是否有可能实现上述情况 我需要超载一些东西吗Foo 您将必须重载强制转换运算符 public class F
  • C++ 中是否有与 PHP 的explode() 函数等效的函数? [复制]

    这个问题在这里已经有答案了 可能的重复 在 C 中分割字符串 https stackoverflow com questions 236129 splitting a string in c 在 PHP 中 explode 函数将获取一个字
  • 如何将System.Windows dll添加到Visual Studio 2010 Express?

    我正在开发一个小型应用程序C and VS2010 as IDE with NET框架4 我想用CaptureSource类以便从笔记本电脑的网络摄像头捕获视频 为此我需要添加一个命名空间System Windows DependencyO
  • 使用多态对象数组进行 JSON 反序列化

    我在涉及多态对象数组的 JSON 反序列化方面遇到问题 我已经尝试过记录的序列化解决方案here https stackoverflow com questions 5186973 json serialization of array w
  • Boost.asio和异步链,unique_ptr?

    我对异步编程不太熟悉 我有一个问题 我的问题如下 给出 boost asio 中 C 11 的 echo server 示例 http www boost org doc libs 1 60 0 doc html boost asio ex
  • 在windows + opengl中选择图形设备

    我知道如何使用 openGL 打开窗口 使用 Win32 或其他工具包 但是当系统有2块显卡时 如何选择要渲染的图形设备 我的编程语言是 C 我专注于 Windows 但任何示例都将受到欢迎 编辑 也许更好地解释我的问题是个好主意 以便添加
  • 如何使用 C# 为 azure devops 变量赋值

    我有 selenium C 测试脚本 可以从浏览器获取令牌 我有两个 azure devops 任务 一个用于执行 selenium 测试 另一个用于执行 API 测试 我想将 selenium 测试获取的令牌传递给 API 测试执行任务

随机推荐