【问题标题】:Get the smallest float larger or equal to a double (and the largest smaller or equal) in C++在 C++ 中获取大于或等于双精度(和最大小于或等于)的最小浮点数
【发布时间】:2013-12-10 09:19:14
【问题描述】:

我正在用双精度 3D 对象制作加速结构 (BVH)。为了提高内存效率,我希望 BVH 具有浮点精度。但我需要以下功能:

  • 获得高于或等于双精度的最低浮点数
  • 获得低于或等于双精度的最高浮点数

这些函数是否存在于标准 C++ 中? (c++11)

谢谢

【问题讨论】:

  • 是的,使用std::numeric_limits<double>::epsilon() 和强制转换(或隐式转换)。

标签: c++ c++11 double rounding


【解决方案1】:

您似乎正在寻找nextafter/nexttoward 函数。

您仍然需要围绕此构建一些逻辑,但这应该为您提供“逐步执行”可表示值所需的构建块。


也许(未经测试)尝试这样的事情:

float get_float(double d)
{
    long double const x = d;

    for (float f1 = d, f2 = f1; ; f2 = f1)
    {
        f1 = std::nexttoward(f2, x);
        if (f1 == f2) { return f1; }
    }
}

【讨论】:

  • 是吗?这些似乎都不符合他正在寻找的内容:给定一个double(精确值),他想要最好的两个浮点数(可能相同)。
  • @JamesKanze:从 double 转换为 float 会不会起作用,然后你就站在一边,然后/朝着另一边迈出一步?
  • @JamesKanze:函数可以用来将double转换为float后得到想要的值。
  • 在将 double d 舍入为浮点 f1 后,测试 f1==d。如果是这样,完成。如果不是,另一个边界是 nexttoward(f1,d)。
  • @PatriciaShanahan:这并不容易,因为你只能比较两个相同类型的东西。但是你可以回到双精度并利用双精度可以表示浮点数的事实(至少在 IEEE754 上)。
【解决方案2】:

没有内置函数。一些快速的实验展示 那:

float fLower = d;
float fUpper = d;
if ( fLower < d ) {
    fUpper = nextafterf( fUpper, FLT_MAX );
} else if ( fUpper > d ) {
    fLower = nextafterf( fLower, -FLT_MAX );
} 

似乎与 g++ 一起工作;在我的小试验中,我没有找到它 必要,但更一般地说,您可能需要使用 -ffloat-store 选项,至少在启用优化的情况下。

有一点值得一提:nextafter 函数 仅在 C++11 中添加到 C++ 中,一般不支持 作为 C++ 函数(例如 std::nextafter 包含 &lt;cmath&gt;)。 如果编译器也支持C99(和g++一样), 那么您可能可以通过包含&lt;math.h&gt; 和通过 将它们视为 C 函数。包括拨打nextafterf, 正如我上面所做的那样,而不是依赖于函数重载 结果是找到floatnextafter 版本。而如果, 像微软一样,编译器不支持C99,他们可能不支持 在场。 (它们在 VS 2012 中不存在,因为 示例。)鉴于此,您最安全的解决方案可能是获取 gcc C 库的源代码,并提取您的代码 需要。 (请注意,IIUC,您必须将代码置于 GPL 下 如果你这样做。)

【讨论】:

  • 谢谢,我会试试的。我正在使用 gcc,但我想保持代码的可移植性,因此无论如何研究 gcc libc 源代码只会给出一个实现,我最终可能会分解浮点尾数/指数并自己完成工作,这不是更多可移植但不受 GPL 限制
猜你喜欢
  • 1970-01-01
  • 2016-09-30
  • 2013-09-02
  • 2011-01-25
  • 2019-09-26
  • 2018-07-09
  • 2021-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多