如何测试无损双精度/整数转换?

2024-03-26

我有一个 double 和一个 int64_t。我想知道它们是否具有完全相同的值,以及将一种类型转换为另一种类型是否不会丢失任何信息。

我当前的实现如下:

int int64EqualsDouble(int64_t i, double d) {
    return (d >= INT64_MIN)
        && (d < INT64_MAX)
        && (round(d) == d)
        && (i == (int64_t)d);
}

我的问题是:这个实现正确吗?如果不是,正确答案是什么?为了正确,它必须不留下假阳性,也不留下假阴性。

一些示例输入:

  • int64EqualsDouble(0, 0.0) 应返回 1
  • int64EqualsDouble(1, 1.0) 应返回 1
  • int64EqualsDouble(0x3FFFFFFFFFFFFFFF, (double)0x3FFFFFFFFFFFFFFF) 应该返回 0,因为 2^62 - 1 可以用 int64_t 精确表示,但不能用 double 表示。
  • int64EqualsDouble(0x4000000000000000, (double)0x4000000000000000) 应该返回 1,因为 2^62 可以在 int64_t 和 double 中精确表示。
  • int64EqualsDouble(INT64_MAX, (double)INT64_MAX) 应返回 0,因为 INT64_MAX 无法精确表示为 double
  • int64EqualsDouble(..., 1.0e100) 应返回 0,因为 1.0e100 无法精确表示为 int64_t。

是的,您的解决方案可以正常工作,因为它的设计初衷就是这样做,因为int64_t在使用类似于二进制 IEEE 754 双精度的平台上,根据定义 (C99 7.18.1.1:1) 以二进制补码表示double类型。它基本上是一样的this one http://gynvael.coldwind.pl/?id=535.

在这些条件下:

  • d < INT64_MAX是正确的,因为它相当于d < (double) INT64_MAX在转换为双精度时,数字INT64_MAX,等于 0x7fffffffffffffff,向上舍入。因此你想要d严格小于结果double避免执行时触发UB(int64_t)d.

  • 另一方面,INT64_MIN,是-0x8000000000000000,是完全可以表示的,这意味着double等于(double)INT64_MIN可以等于一些int64_t并且不应该被排除在外(并且这样的double可以转换为int64_t不会触发未定义的行为)

不言而喻,由于我们专门使用了关于整数和二进制浮点的 2 补码的假设,因此在不同平台上的这种推理不能保证代码的正确性。采用具有二进制 64 位浮点和 64 位 1 的补码整数类型的平台T。在那个平台上T_MIN is -0x7fffffffffffffff。转换为double该数字的四舍五入,结果是-0x1.0p63。在该平台上,使用编写的程序,使用-0x1.0p63 for d使前三个条件为真,导致未定义的行为(T)d, 因为从整数到浮点的转换中的溢出是未定义的行为 http://blog.frama-c.com/index.php?post/2013/10/09/Overflow-float-integer.


如果您可以访问完整的 IEEE 754 功能,则有一个更短的解决方案:

#include <fenv.h>
…
#pragma STDC FENV_ACCESS ON
feclearexcept(FE_INEXACT), f == i && !fetestexcept(FE_INEXACT)

该解决方案利用从整数到浮点的转换,当且仅当转换不精确时设置 INEXACT 标志(即,如果i不能完全表示为double).

INEXACT 标志保持未设置状态并且f等于(double)i当且仅当f and i在各自的类型中表示相同的数学值。

这种方法要求编译器收到代码访问 FPU 状态的警告,通常使用#pragma STDC FENV_ACCESS on但这通常不受支持,您必须使用编译标志。

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

如何测试无损双精度/整数转换? 的相关文章

  • 从 Invoke 方法获取 RETURN

    我正在尝试从另一个线程上的列表框项目中读取值 我尝试创建一种新方法来运行调用命令 我可以设法将命令发送到列表框 例如通过调用方法添加 但我似乎无法得到响应 我似乎无法获取该项目的值 我尝试了几种方法 一旦我将它从空变为字符串 事情就开始变得
  • C# 和月历,选择多个日期

    我正在制作一个程序 可以帮助人们用 C 为某个部门 预订 订单 他们需要能够选择不同月份的多个日期 我更愿意拥有它 这样他们就可以单击一个日期 然后按住 Shift 键单击另一个日期以选择这两个日期之间的所有日期 并控制单击以进行单选 取消
  • 使用 Xamarin.Forms 和 Zxing 生成 QR 码

    我在网上看到了很多关于这个的内容 旧帖子 但似乎没有什么对我有用 我正在尝试从字符串中生成二维码并将其显示在应用程序中 这就是我一开始的情况 qrCode new ZXingBarcodeImageView BarcodeFormat Ba
  • .pdbs 会减慢发布应用程序的速度吗?

    如果 dll 中包含 pdb 程序调试 文件 则行号将出现在引发的任何异常的堆栈跟踪中 这会影响应用程序的性能吗 这个问题与发布与调试 即优化 无关 这是关于拥有 pdb 文件的性能影响 每次抛出异常时都会读取 pdb 文件吗 加载程序集时
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • 判断串口是普通COM还是SPP

    我正在寻找一种方法来确定 COM 是标准 COM 还是 SPP COM 也称为 COM 设备的电缆替换蓝牙适配器 我有一个可以在 USB COM gt USB 和蓝牙下工作的设备 并且蓝牙接口可以与 SPP 一起工作 我目前正在使用Syst
  • 名称查找、实例化点 (POI) 和基本类型

    以下代码针对 X 进行编译 但不适用于 double struct X void foo double void foo X namespace NN struct A void foo A foo double error foo not
  • 为什么 std::function 不是有效的模板参数,而函数指针却是?

    我已经定义了名为的类模板CallBackAtInit其唯一目的是在初始化时调用函数 构造函数 该函数在模板参数中指定 问题是模板不接受std function作为参数 但它们接受函数指针 为什么 这是我的代码 include
  • 编写具有多种类型的泛型扩展方法时的类型推断问题

    我正在为 IEnumerable 编写一个通用扩展方法 用于将对象列表映射到另一个映射对象列表 这就是我希望该方法的工作方式 IList
  • 如何在新窗口中打开图像或pdf文件?

    我有一个 gridview 它包含文件名和文件路径 图像和 pdf 格式文件 其中我使用了模板字段 在该字段下放置了 1 个图像按钮 单击该图像按钮 即 查看 按钮 时 我想在新窗口中打开所选文件 这是我的代码 protected void
  • 从点云检测平面集

    我有一组点云 我想测试3D房间中是否有角落 所以我想讨论一下我的方法 以及在速度方面是否有更好的方法 因为我想在手机上测试它 我将尝试使用霍夫变换来检测线 然后我将尝试查看是否有三条线相交 并且它们也形成了两个相交的平面 如果点云数据来自深
  • WinForms - 加载表单时如何使用 PaintEventArgs 运行函数?

    我试图理解图形 在 Graphics FromImage 文档中 它有这样的示例 private void FromImageImage PaintEventArgs e Create image Image imageFile Image
  • 选择 asp.net CheckBoxList 中的所有项目

    ASP NET 和 C 我想要一个带有 全选 项目的复选框列表 当这个特定项目是 已选择 所有其他都将被选择 也 当选择被删除时 这个项目 也将来自所有人 其他物品 选中 取消选中 任何其他项目只会有一个 对特定项目的影响 无论选择状态如何
  • WPF DataGrid - 在每行末尾添加按钮

    我想在数据网格的每一行的末尾添加一个按钮 我找到了以下 xaml 但它将按钮添加到开头 有人知道如何在所有数据绑定列之后添加它吗 这会将按钮添加到开头而不是末尾
  • 不使用放置 new 返回的指针时的 C++ 严格别名

    这可能会导致未定义的行为吗 uint8 t storage 4 We assume storage is properly aligned here int32 t intPtr new void storage int32 t 4 I k
  • 在二进制数据文件的标头中放入什么

    我有一个模拟 可以读取我们创建的大型二进制数据文件 10 到 100 GB 出于速度原因 我们使用二进制 这些文件依赖于系统 是从我们运行的每个系统上的文本文件转换而来的 所以我不关心可移植性 当前的文件是 POD 结构的许多实例 使用 f
  • 运行 xunit 测试时无法将输出打印到控制台窗口

    public class test2InAnotherProject private readonly ITestOutputHelper output public test2InAnotherProject ITestOutputHel
  • 如何在 Razor 编辑视图中显示选中的单选按钮 Asp net core mvc

    尽管 Razor 视图中的 Asp 网络核心代码 model List
  • 如何在c中断言两个类型相等?

    在 C 中如何断言两种类型相等 在 C 中 我会使用 std is same 但搜索 StackOverflow 和其他地方似乎只能给出 C 和 C 的结果 在C中没有办法做到这一点吗 请注意 这不是询问变量是否具有某种类型 而是询问两个类

随机推荐

  • Three.js ShaderMaterial 灯光问题

    你好 这是我的代码的一部分 地球仪 function createGlobe var normalMap THREE ImageUtils loadTexture images earth normal 2048 jpg var surfa
  • 在 django admin 过滤器 list_filter 中选择多个选项?

    目前我通过 django 管理界面中的某些选项进行过滤 例如 假设我按 按状态 过滤 是否可以选择多个状态来过滤结果 这是过滤器的屏幕截图 我可以从此列表中选择多个项目吗 不在管理 UI 中 但如果修改 URL 则可以使过滤条件更加复杂 例
  • EF 4.3(代码优先)- 确定何时将项目添加到虚拟 ICollection 属性

    当从查询加载 ICollection 虚拟成员时 有什么方法可以确定实际项目何时添加到 ICollection 虚拟成员中 希望下面的代码能够证明我的观点 public class DbAppointment public DbAppoin
  • F# 类型和循环

    我正在编写一个创建一副纸牌的 F 教程 列出了类型 但我无法理解如何循环遍历类型来创建完整套牌的地图 我期望做类似的事情 Foreach rank in ranks Foreach suit in suits somehow combine
  • 通过 Azure KeyVault 禁止控制台日志记录

    我正在 Net Core 2 控制台应用程序中使用 C 访问 Azure 密钥保管库 每当应用程序运行时 当我从保管库检索机密时 控制台窗口都会收到如下消息 2017 12 26T18 03 49 8610049Z 29c98a86 9e1
  • 如何为 iOS 和 macOS 编译 libffi?

    我正在尝试使用libffi https github com atgreen libffi在我的一个项目中 但我似乎无法为 iOS 或 macOS 就此而言 进行编译 以下是我在构建 iOS 模拟器时遇到的各种错误之一 bash src a
  • Python 3 async for 循环中的类型错误

    我正在学习 Python 相对较新的异步功能 我发现这个在PEP 492 https www python org dev peps pep 0492 example 2 以下是一个实用程序类 它将常规迭代转换为 异步的 虽然这不是一件非常
  • 尝试运行不和谐机器人时出错(python)

    File dban py line 1 in
  • 更改消息名称

    这是我的 WSDL 的一部分 我正在使用代码优先的方法
  • 检查产品变体是否在 Woocommerce 的购物车中

    我正在尝试显示产品的变体是否已在购物车中 在单个产品页面中 产品 ID 与购物车对象中的产品的简单比较不适用于可变产品 因为变体 ID 是使用 ajax 加载的 这是我的代码 适用于产品类型不是变量的情况
  • Python“decimal”包给出错误的结果

    我尝试通过设置来计算以下内容getcontext prec 800 gt gt gt from decimal import gt gt gt getcontext prec 800 gt gt gt Decimal 22 0 Decima
  • 使用jquery和参数调用WCF服务

    好吧 这是这些基本问题之一 但我现在已经用谷歌搜索和调试了两个小时 但错误没有消失 简单场景 WCF 服务 其方法带有我想通过 jquery 调用的参数 我可以调用不带参数的方法 但是使用参数时 调用永远不会到达 NET 中的断点 服务器代
  • 执行 .bat 文件时启用按钮

    我有一个带有打开按钮和后退按钮的表单 我通过打开按钮打开批处理文件 在执行批处理文件时 其他按钮被禁用 我想启用这些按钮 请帮我 运行批处理文件代码 private void openActionPerformed java awt eve
  • NotificationCompat.Builder 缺少 build() 方法

    我想做的正是他所做的 Android 时间通知 https stackoverflow com questions 17053996 android notification at time但在我的 AlarmReceiver 类中 出现错
  • HttpInterceptor 根据其他可观察值的值更改响应主体

    有些我似乎无法根据另一个可观察值的值来更改响应主体 而我只能在检索响应后才能获得该值 更改请求非常简单 我不知道如何处理响应 Injectable export class MyHttpInterceptor implements Http
  • Spark MLlib:为每个数据组构建分类器

    我已经标记了向量 LabeledPoint staged 由一些组号组成 对于每个组 我需要创建独立逻辑回归分类器 import org apache log4j Level Logger import org apache spark m
  • 我将如何评估某个公式?

    我有一个多维数组列表 我向用户询问一个公式 然后我对其进行评估 问题是我得到这样的用户输入 a1 a2 12 a3 问题是 a1 a2 和 a3 指的是列 我必须将其评估为一定的值 我完全不知道如何解决这个问题 任何建议或指导都会很棒 此外
  • Python Spyder 选择显示绘图的位置和时间

    我在 Windows 10 中使用 Spyder3 1 2 IDE 和 Python 3 5 想知道如何选择是在 iPython 控制台还是在单独的窗口中显示我的绘图 我找到了这个其他问题 https stackoverflow com q
  • iOS 11 - 使用大标题模式时的 UINavigationItem titleView

    我试图理解这是一个错误还是预期的行为 On iOS 10之前我们可以设置一个自定义标题 使用navigationItem titleView On iOS 11 当设置我们的navigationItem largeTitleDisplayM
  • 如何测试无损双精度/整数转换?

    我有一个 double 和一个 int64 t 我想知道它们是否具有完全相同的值 以及将一种类型转换为另一种类型是否不会丢失任何信息 我当前的实现如下 int int64EqualsDouble int64 t i double d ret