当前位置:  开发笔记 > 编程语言 > 正文

如何以最小增量(或接近它)改变浮点数?

如何解决《如何以最小增量(或接近它)改变浮点数?》经验,为你挑选了2个好方法。

我有一个double价值f,并想要一个稍微大一点(或更小)的方法来获得一个新的值,该值尽可能接近原始值但仍严格大于(或小于)原始值.

它不必靠近最后一位 - 更重要的是,我所做的任何改变都能保证产生不同的值,而不是回到原始值.



1> Nils Pipenbr..:

检查math.h文件.如果你很幸运,你可以定义nextafternextafterf功能.它们以便携式和平台独立的方式完成您想要的任务,并且是C99标准的一部分.

另一种方法(可能是后备解决方案)是将你的浮点数分解为尾数和指数部分.增量很简单:只需在尾数中添加一个即可.如果出现溢出,则必须通过递增指数来处理此问题.减量的工作方式相同.

编辑:正如评论中指出的那样,只需增加浮点数的二进制表示就足够了.尾数溢出将增加指数,这正是我们想要的.

简而言之,这与nextafter的做法相同.

但这不是完全可移植的.您将不得不处理endianess和不是所有机器都有IEEE浮动的事实(好的 - 最后一个原因是更具学术性).

处理NAN和infinite也有点棘手.你不能简单地增加它们,因为它们是定义而不是数字.


你特别不想处理尾数溢出,因为溢出将转移到你想要的指数上.
这很酷:)现在可以贬低我的答案的白痴说,请撤消它吗?
我认为负值也必须区别对待.如果递增,结果将比原始值更负.顺便说一句 - 我刚刚在VS.NET 2008实现中反汇编了nextafter.它们比我预期的要多得多.

2> 小智..:
u64 &x = *(u64*)(&f);
x++;

是的,认真的.

编辑:有人指出,这不适用于-ve数字,Inf,Nan或溢出.以上是更安全的版本

u64 &x = *(u64*)(&f);
if( ((x>>52) & 2047) != 2047 )    //if exponent is all 1's then f is a nan or inf.
{
    x += f>0 ? 1 : -1;
}


未定义的行为,违反严格的别名规则
推荐阅读
夏晶阳--艺术
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有