使用CC++ nextafternexttoward函数无法获得下一个32位浮点值

使用CC++ nextafternexttoward函数无法获得下一个32位浮点值,第1张

概述使用C或C,我希望在循环中递增所有可表示的32位浮点数的范围,类似于可以递增由32位整数表示的所有不同值的方式. 就像是: for(float f = FLOAT_MIN; f< MAX; f = Next_Float(f)) {…} 我认为我可以使用标准数学库中的“nexttoward”或“nextafter”函数来完成该任务.见http://www.cplusplus.com/referenc 使用C或C,我希望在循环中递增所有可表示的32位浮点数的范围,类似于可以递增由32位整数表示的所有不同值的方式.

就像是:
for(float f = float_MIN; f< MAX; f = Next_float(f))
{…}

我认为我可以使用标准数学库中的“nexttoward”或“nextafter”函数来完成该任务.见http://www.cplusplus.com/reference/cmath/nextafter/

现在,当我测试带有双打或长双打的“nexttoward”或“nextafter”函数并在Ubuntu 13.04上使用g 4.7进行编译时,我没有遇到任何问题.查看测试代码:

#include <math.h>   #include <iostream>#include <iomanip>int main (){    double f = 0.1;    for(int i = 0; i < 5; ++i)    {    //marginally increment f in the upper direction.    f = nexttoward(f,999.999);    std::cout << std::setprecision(70) << f << std::endl;    std::cout << nexttoward(f,999.999) << std::endl;    }  return 0;}

该程序的浮点输出值按预期稳步增长:

ubuntu @ ubuntu:〜$g -o temp~ / temp.cpp

ubuntu @ ubuntu:〜$./temp

0.10000000000000001942890293094023945741355419158935546875
0.100000000000000033306690738754696212708950042724609375
0.100000000000000033306690738754696212708950042724609375
0.10000000000000004718447854656915296800434589385986328125
0.10000000000000004718447854656915296800434589385986328125
0.1000000000000000610622663543836097232997417449951171875
0.1000000000000000610622663543836097232997417449951171875
0.10000000000000007494005416219806647859513759613037109375
0.10000000000000007494005416219806647859513759613037109375
0.100000000000000088817841970012523233890533447265625

Ubuntu的@ Ubuntu的:〜$

但是当我尝试使用浮点数而不是双精度数时,“nexttoward”和“nextafter”函数使我失败 – 函数似乎返回比32位浮点数更高精度的值,并且当我将返回值赋给我的32位浮点数时,浮动保持其原始值而不是上升到下一个更高的值.请参阅示例代码和输出:

#include <math.h>    #include <iostream>#include <iomanip>int main (){    float f = 0.1f;    for(int i = 0; i < 10; ++i)    {    //marginally increment f in the upper direction.    f = nexttoward(f,999.999f);    std::cout << std::setprecision(70) << f << std::endl;    std::cout << nexttoward(f,999.999f) << std::endl;    }  return 0;}

请注意,“nexttoward”的第二个输出值具有更高的精度,并且f保持相同的值:

ubuntu @ ubuntu:〜$g -o temp~ / temp.cpp

ubuntu @ ubuntu:〜$./temp

0.100000001490116119384765625
0.10000000149011613326255343281445675529539585113525390625
0.100000001490116119384765625
0.10000000149011613326255343281445675529539585113525390625
0.100000001490116119384765625
0.10000000149011613326255343281445675529539585113525390625
0.100000001490116119384765625
0.10000000149011613326255343281445675529539585113525390625
0.100000001490116119384765625
0.10000000149011613326255343281445675529539585113525390625
0.100000001490116119384765625
0.10000000149011613326255343281445675529539585113525390625
0.100000001490116119384765625
0.10000000149011613326255343281445675529539585113525390625
0.100000001490116119384765625
0.10000000149011613326255343281445675529539585113525390625
0.100000001490116119384765625
0.10000000149011613326255343281445675529539585113525390625
0.100000001490116119384765625
0.10000000149011613326255343281445675529539585113525390625

我想增加所有32位浮点值,而不是所有64位双精度值 – 增加所有双精度值的时间太长.

如何解决此问题并实现高效,方便,可移植的方式迭代32位浮点变量的范围?

解决方法 nextafter和nexttoward函数接受double类型的参数并返回double类型的结果.

对于float,使用相应的nextafterf和nexttowardf函数.

这是几乎所有在< math.h>中声明的数学函数的一般规则.例如,有三个平方根函数:

> sqrtf(浮动)
> sqrt(双倍)
> sqrtl(长双)

(float和long double版本由C99添加,并且可能不受所有实现的支持.)

如果对类型使用了错误的函数,编译器就不会抱怨;它会悄悄地将参数转换为预期的类型,并根据您对它的处理方式转换结果.

这是针对C.如果你使用#include< cmath>,C为类型float和long double添加了数学函数的重载版本(没有f或l后缀).因此,如果将代码编译为C,则这些函数应该按预期运行. (< math.h>和< cmath>之间可能存在差异;在任何情况下,您都应该将后者用于C.)

您的问题被标记为C和C,这在该领域有显着差异.

(C99还添加了一个< tgmath.h>标头,它提供了与C的重载函数类似的特定于类型的宏.)

总结

以上是内存溢出为你收集整理的使用C/C++ nextafter / nexttoward函数无法获得下一个32位浮点值全部内容,希望文章能够帮你解决使用C/C++ nextafter / nexttoward函数无法获得下一个32位浮点值所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1215542.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存