将浮点数转换为无符号短时的舍入问题
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
【讨论】:
以上是关于将浮点数转换为无符号短时的舍入问题的主要内容,如果未能解决你的问题,请参考以下文章