如果 std::numeric_limits::is_iec559 为 true,这是否意味着我可以以明确定义的方式提取指数和尾数?

2023-12-19

我已经构建了一个自定义版本frexp https://en.cppreference.com/w/cpp/numeric/math/frexp:

auto frexp(float f) noexcept
{
    static_assert(std::numeric_limits<float>::is_iec559);

    constexpr uint32_t ExpMask = 0xff;
    constexpr int32_t ExpOffset = 126;
    constexpr int MantBits = 23;

    uint32_t u;
    std::memcpy(&u, &f, sizeof(float)); // well defined bit transformation from float to int

    int exp = ((u >> MantBits) & ExpMask) - ExpOffset; // extract the 8 bits of the exponent (it has an offset of 126)

    // divide by 2^exp (leaving mantissa intact while placing "0" into the exponent)
    u &= ~(ExpMask << MantBits); // zero out the exponent bits
    u |= ExpOffset << MantBits; // place 126 into exponent bits (representing 0)

    std::memcpy(&f, &u, sizeof(float)); // copy back to f
    return std::make_pair(exp, f);
}

通过检查is_iec559 https://en.cppreference.com/w/cpp/types/numeric_limits/is_iec559我确定float满足

IEC 559 (IEEE 754) 标准的要求。

我的问题是:这是否意味着我正在执行的位操作定义良好并且可以执行我想要的操作?如果没有,有办法解决吗?

我测试了它的一些随机值,它似乎是正确的,至少在使用 msvc 编译的 Windows 10 上wandbox https://wandbox.org/permlink/VdKLHXtSaqB6B4KR。但请注意,(故意)我没有处理次正规的边缘情况,NaN, and inf.

如果有人想知道我为什么这样做:在基准测试中我发现这个版本frexp速度高达 15 倍std::frexp在 Windows 10 上。我还没有测试过其他平台。但我想确保这不仅仅是巧合,而且将来可能会停止。

Edit:

正如评论中提到的,字节顺序可能是一个问题。有人知道吗?


“这是否意味着我正在做的位操作是明确定义的……”

TL;DR;,根据“明确定义”的严格定义:no.

你的假设是可能是正确的但不是明确定义,因为无法保证位宽或实现float。从第 3.9.1 节开始:

浮点类型共有三种:float、double 和 long double。 double 类型至少提供与 float 一样多的精度,而 long double 类型至少提供与 double 一样多的精度。 float 类型的值集合是 double 类型的值集合的子集; double 类型的值集是 long double 类型的值集的子集。浮点类型的值表示是实现定义的。

The is_iec559子句仅符合:

当且仅当类型符合 IEC 559 标准时为真

如果一个文字精灵给你写了一个糟糕的编译器,并做了float = binary16, double = binary32, and long double = binary64,并做了is_iec559对于所有类型都是如此,它仍然遵守标准。

这是否意味着我可以以明确的方式提取指数和尾数?

TL;DR;,由 C++ 标准的有限保证:no.

假设你使用float32_t and is_iec559是真的,并且从所有规则中逻辑地推断出它只能是binary32没有陷阱表示,并且您正确地论证了memcpy是为相同宽度的算术类型之间的转换定义良好的,并且不会破坏严格的别名。即使有所有这些假设,行为也可能是明确定义但这只是likely并不是保证你可以用这种方式提取尾数。

IEEE 754 标准和 2 的补码位串编码,以及行为memcpy被描述为使用bytes。虽然假设位串是合理的uint32_t and float32_t将以相同的方式编码(例如相同的字节序),标准对此没有保证。如果位串以不同的方式存储,并且您移动并屏蔽复制的整数表示形式以获得尾数,则答案将不正确,尽管memcpy行为被明确定义。

正如评论中提到的,字节顺序可能是一个问题。有人知道吗?

至少一些架构 https://en.wikipedia.org/wiki/Endianness#Floating-point_and_endianness对浮点寄存器和整数寄存器使用了不同的字节序。同一个链接表示,除了小型嵌入式处理器之外,这不是一个问题。我完全信任维基百科的所有主题,并拒绝做任何进一步的研究。

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

如果 std::numeric_limits::is_iec559 为 true,这是否意味着我可以以明确定义的方式提取指数和尾数? 的相关文章

随机推荐

  • 使用 Doctrine 2 自动引用保留字

    有没有办法在使用时自动引用 Doctrine 2 的保留字 entityManager gt find entity id 使用查询生成器时可以完成此操作 但应该有一个全局配置设置来执行此操作 我不想在保留字的注释中指定它 这是我不久前向
  • Java SDK 的 Couchbase 连接超时

    我按照 couchbase 教程连接到远程 couchbase 服务器 但在我尝试打开默认存储桶后 连接超时失败 我已检查是否可以在我的计算机上打开 couchbase 服务器页面 192 xx xx xx 8091 这是我的Java代码
  • 如何使用 css 滤镜获得图像:模糊和锐利边缘?

    我想在悬停时模糊图像 问题是图像的边缘也模糊得令人不快 在 Fiddle 中 您可以在绿色背景下清楚地看到它 如果我缩放图像 即 1 2 它最终会解决问题 但在过渡过程中 模糊的边缘仍然出现 有什么想法如何使边缘具有这种效果 http js
  • HTML5 上传前预先调整图像大小

    这是一个面条刮刀 请记住 我们有 HTML5 本地存储和 xhr v2 等等 我想知道是否有人可以找到一个可行的示例 甚至只是对这个问题给出 是 或 否 是否可以使用新的本地存储 或其他 预先调整图像大小 以便不知道如何调整图像大小的用户可
  • Swift:@objc(...) 属性

    在 Apple 生成的代码中 Core DataNSManagedObject子类 例如 我看到这个 objc LPFile public class LPFile NSManagedObject 我的问题是 为什么是 objc声明如上所述
  • 我需要与多个远程参与者系统进行通信

    我正在使用 akka Net 开发一种插件架构 其中包含一个或多个插件的每个 dll 都被加载到自己的中AppDomain并且新的参与者系统被初始化 准备接收来自 主机 的消息 我试图让它与多个插件一起工作 但我却陷入困境 所以主机配置如下
  • 条形图中的渐变填充

    我正在观察不同人群的行为 称为Clusters在此数据集中 以及他们对所使用的浏览器类型的偏好 我想创建一个条形图 显示使用每种类型浏览器的每个集群的百分比 下面是一些生成类似数据集的代码 请忽略每个簇的百分比加起来不会等于 1 brows
  • Clang++-3.7 CRTP 编译错误“父级模板参数中没有命名成员”

    在下面的代码中 我尝试使用 CRTP 来使用父类中子类的静态成员 值 当使用带有 pedantic 标志的 g 5 2 1 编译代码时 我能够按预期编译 并且在执行时c print value and Child
  • 从包含数百万个文件的目录中精确匹配地高效查找数千个文件 (bash/python/perl)

    我在 Linux 上 试图从包含数百万个文件的目录 SOURCE DIR 中查找数千个文件 我有一个需要查找的文件名列表 存储在单个文本文件 FILE LIST 中 该文件的每一行都包含与 SOURCE DIR 中的文件相对应的单个名称 并
  • Visual Studio 卡在生成代码中

    当我使用 Visual Studio 构建 C 项目时 进程陷入困境生成代码 1 gt Rebuild All started Project myWrapper Configuration Release Win32 1 gt funzi
  • iOS 重新安装应用程序不会清除徽章

    我已通过本地通知将应用程序的徽章编号设置为 1 然后我卸载该应用程序 当我重新安装它时 徽章仍然存在 这是 iOS 错误还是有办法在卸载时清除徽章 thanks 徽章计数由操作系统维护 独立于应用程序 卸载 删除 应用程序时 操作系统会保留
  • 为什么 PyQt 执行我的操作三次?

    我对 PyQt 还是个新手 但我真的不知道为什么会发生这种情况 我有一个像这样创建的主窗口 class MainWindow QtGui QMainWindow initialize def init self Call parent co
  • shopkick 应用程序 UI 小部件

    请参阅下面的链接 http itunes apple com app id383298204 mt 8 http itunes apple com app id383298204 mt 8 有 showpick 应用程序的屏幕截图 其中有一
  • React中删除项目后如何刷新页面?

    我的问题是 当我单击删除按钮时 我可以从表中删除该项目 但我需要手动刷新页面 如何解决自动刷新 有人能解决我的问题吗 我还在下面附上了我的代码部分 这是我的代码部分 还有 Home 组件和 RowCreator 组件 import Reac
  • Puppeteer:Chromium 实例在 browser.disconnect 后在后台保持活动状态

    我的环境 傀儡师版本 3 1 0 平台 操作系统版本 Windows 10 Node js 版本 12 16 1 我的问题是 我有一个for of使用 puppeteer 循环访问 3000 多个网址 我用puppeteer connect
  • MSAA 的抗锯齿问题、深度绘制 CSG 和 FBO

    我已经重新实现了OpenCSG http www opencsg org适用于现代 OpenGL 版本 PixelFormat属性 NSOpenGLPFAColorSize 24 NSOpenGLPFAAlphaSize 8 NSOpenG
  • React.js 破坏了dispatchEvent

    例如 我在反应中添加事件处理程序 div 然后我调度事件 let clickEvt new MouseEvent click bubbles false cancelable true elm dispatchEvent clickEvt
  • C++ 汇编器输出 - 如何实现引用

    C 和汇编工具链 GNU 我有以下 C 代码 int main void int i 33 j 66 swap i j cout lt lt i lt lt lt lt j lt lt endl return 0 如果我现在检查生成的汇编代
  • 您会将 SQLite 数据库文件放置在 iPhone 应用程序中的什么位置?

    当我最初为我的应用程序创建一个带有预先插入的数据集的 SQLite 数据库文件时 我必须将该文件放置在我的 Xcode 项目中的某个位置 以便它可以访问我的 iPhone 应用程序 我想 资源 是正确的地方 在 iPhone 应用程序中部署
  • 如果 std::numeric_limits::is_iec559 为 true,这是否意味着我可以以明确定义的方式提取指数和尾数?

    我已经构建了一个自定义版本frexp https en cppreference com w cpp numeric math frexp auto frexp float f noexcept static assert std nume