mygeek 发表于 2017-5-24 10:14:26

【寻求帮助】数据类型转换异常

小弟刚刚入门,下面的程序是要对小于零的数字变换成整数,以便下一步送给数码管显示,可是变换结果不对没找到原因,请各位大侠帮忙看一下问题在哪里?

//=========程序开始=============
float a;
float b;
int c;
int d;

void setup()
{
a = 0.05;                                        //目标数字是0.05,要变换成5送给数码管
b = 0;
c = 0;
d = 0;
Serial.begin(9600);
}

void loop()
{
for (int i = 1; i <= 2; i = i + (1)) {    //数字有很多个,这里仅仅是用循环验证第一个
    b = a * pow(10, i);                        //用乘法把小数变成整数
    c = int(b);                                     //类型转换,原因是%取余必须是整数型
    d = c % 10;                                  //转换之后取余
    Serial.println(String(String(String("b") + String(i)) + String(" = ")) + String(b));
    Serial.println(String(String(String("c") + String(i)) + String(" = ")) + String(c));
    Serial.println(String(String(String("d") + String(i)) + String(" = ")) + String(d));
}
while (true);

}
//=========程序结束=====================

以下是串口打印结果,c2应该是把b2的5.00转换成5才对,为什么等于4呢?
b1 = 0.50
c1 = 0
d1 = 0
b2 = 5.00
c2 = 4
d2 = 4

迷你强 发表于 2017-5-24 10:33:32

小数处理为整数,强制类型转换应该就可以了吧。。直接抛弃后面的精度

mygeek 发表于 2017-5-24 10:44:23

迷你强 发表于 2017-5-24 10:33
小数处理为整数,强制类型转换应该就可以了吧。。直接抛弃后面的精度

就是这么想的啊,b= 0.05 x (10^2) = 5.00,然后用c = int(b) 强制转换成5,可是看打印结果转换成4了,为什么呢?

Super169 发表于 2017-5-24 14:52:01

这是 float 的精确度问题.你看到的 0.05, 在电脑世界, 以二进储存时, 是不能做到绝对的 0.05, 只是以最接近的二进数值去储存.你的基数本身就有误差, 之後只是把它放大了.

要知道为何是 4, 为什麽不看看c = int(b * 10) 又或 c = int(b * 100) 是什麽呢?

解决的方法, 可以简单地以 round 去代替 int.round 基本上已经可以应付大部份因为二进储存而做成的误差.

mygeek 发表于 2017-5-24 15:59:32

Super169 发表于 2017-5-24 14:52
这是 float 的精确度问题.你看到的 0.05, 在电脑世界, 以二进储存时, 是不能做到绝对的 0.05, 只是以最接 ...

真是一语点醒啊!
增加了中间变量 e=b x 1000测试,执行结果是 e = 4999,确实存在精度误差。
把程序改成 c = round(b),结果正确了。
不过要注意的是 round不是四舍五入,会把 b = 0.5 取整变成1,对于本程序来说还要处理一下。
总之问题原因找到了,再次感谢!:handshake
页: [1]
查看完整版本: 【寻求帮助】数据类型转换异常