将浮点数转换为无符号短时的舍入问题

Posted

技术标签:

【中文标题】将浮点数转换为无符号短时的舍入问题【英文标题】:Rounding issue while conver float to unsigned short 【发布时间】:2014-09-02 10:55:47 【问题描述】:

在将浮点数转换为无符号整数时,我得到了错误的值

TMAC_PAYLOAD_SCALE = 0.10
Data = (unsigned short)(mData / TMAC_PAYLOAD_SCALE);
189.20/0.10 = 1891  (I am expecting 1892)
184.59/0.10 = 1845  (I am expecting 1846)

尝试了round和ceil函数,但仍然得到错误的答案

【问题讨论】:

round 应该给出正确的结果 - 你确定你使用正确吗? Looks fine to me (我在第一个中使用了圆形,但第二个也需要它)。在第一种情况下需要 round 只是因为浮点计算的乐趣:10.0*189.20 给了你正确的答案。在第二种情况下,这是由于强制转换以某种方式截断了数据,因此 1845.9 变为 1845。 @PaulR 如果是 VC,是的。但一般来说,double 类型(由round 返回)不保证是 IEEE 754 并且允许所有整数的精确表示。因此,我们可能会遇到截断结果低于预期的情况。 (我试图在我的回答中用float 来说明它。) 【参考方案1】:

如果是C++编译器uses IEEE 754你可以试试round函数:

Data = (unsigned short)round(mData / TMAC_PAYLOAD_SCALE);

但是,假设除法的结果是非负的,下面的方法可能更好:

Data = (unsigned short)(mData / TMAC_PAYLOAD_SCALE + 0.5);

原因是对于浮点整数转换,小数部分被丢弃了。因此,如果舍入函数不能表示精确的整数值N,并返回一个“略小于”N 的值,那么在转换后我们得到N-1

这个问题可以通过以下(IEEE 754 兼容)代码来说明:

int a = 16777217;
float f = a; // not double
int b = f;
cout << a << " " << b << endl;

哪个输出

16777217 16777216

虽然所描述的问题在 IEEE 754 和 round 函数的情况下不应该发生(因为 round 返回 double 允许精确表示整数),但第一种方法看起来仍然不是很方便,因为我们必须记住所有这些假设。

【讨论】:

我确实喜欢这个 Data = round(mData) * 100) / 100; @Sijith 您需要对“/”操作的结果进行舍入,而不是一个参数。 (括号是不平衡的顺便说一句。) @Sijith 我更新了答案,你也可以看看第二个选项。【参考方案2】:

我尝试过的-

#include <stdio.h>
#include<math.h>
int main ()


        printf("%hd\n",(unsigned short)ceil(189.20/0.10)); // you can use ceilf also
        printf("%hd\n",(unsigned short)floor(184.59/0.10));

        return 0;

输出-

root@sathish1:~/My Docs/Programs# ./a.out 
1892
1845

【讨论】:

以上是关于将浮点数转换为无符号短时的舍入问题的主要内容,如果未能解决你的问题,请参考以下文章

将特征矩阵转换为无符号字符 *

opencv c++:将图像矩阵从无符号字符转换为浮点数

如何在python中将有符号整数转换为无符号整数

如何将以“\ 0”开头的char *转换为无符号整数? [关闭]

std::cbrt 的舍入错误?

在 Swift 中将有符号转换为无符号