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

如何使用偏置进行浮点舍入(始终向上或向下舍入)?

如何解决《如何使用偏置进行浮点舍入(始终向上或向下舍入)?》经验,为你挑选了1个好方法。

我想要一个带有偏差的浮子,要么总是向下,要么总是向上.在我需要的代码中有一个特定的点,程序的其余部分应该像往常一样舍入到最接近的值.

例如,我想要舍入到最接近的1/10的倍数.最接近7/10的浮点数约为0.69999998807,但最接近8/10的数字约为0.80000001192.当我舍入数字时,这是我得到的两个结果.我宁愿以同样的方式对它们进行四舍五入.7/10应该舍入到0.70000004768并且8/10应该舍入到0.80000001192.

在这个例子中,我总是四处寻找,但我有一些地方,我想要总是向下舍入.幸运的是,我只是处理每个地方的正面价值观.

我用来绕线的是floor(val * 100 + 0.5) / 100.我用C++编程.



1> Pieter..:

我认为实现这一目标的最佳方法是依赖于这样的事实:根据IEEE 754浮点标准,浮点位的整数表示按字典顺序排列为2补码整数.

即你可以简单地添加一个ulp(最后一个位置的单位)来获得下一个浮点表示(如果它更小,它将总是略大于你的阈值,因为圆误差最多为1/2 ulp)

例如

 float floatValue = 7.f/10;
 std::cout << std::setprecision(20) << floatValue << std::endl;
 int asInt = *(int*)&floatValue;
 asInt += 1;
 floatValue = *(float*)&asInt;
 std::cout << floatValue << std::endl;

打印(在我的系统上)

 0.69999998807907104492
 0.70000004768371582031

要知道何时需要添加一个ulp,你必须依赖于floor和舍入的差异floor

 if (std::floor(floatValue * 100.) != std::floor(floatValue * 100. + 0.5)) {
    int asInt = *(int*)&floatValue;
    asInt += 1;
    floatValue = *(float*)&asInt;
 }

将0.69 ..正确转换为0.70 ..但单独留下0.80 ..

请注意,浮点数在应用100.之前通过乘法被提升为double floor.

如果你不这样做,你就有可能陷入这样的境地

 7.f/10.f * 100.f

(精度有限)浮点表示为70.00 ...


我刚刚在C99中发现了一个叫做nexttoward的函数,它可以用来递增ulp,很好地掩盖了比特的错误.http://www.penguin-soft.com/penguin/man/3/nextafter.html
推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有