请教:Keil C UV4 中unsigned long型变量运算后输出为float型出错。

2020-01-30 13:43发布

环境51,Keil UV4
写一段程序用于对两组数据求一元线性回归,在执行到这句时遇到问题:
float VTk;
unsigned long SigmaVjTj,SigmaVj,SigmaTj;

VTk=(float)(SigmaVjTj-SigmaVj*SigmaTj/j)/(SigmaVj2-SigmaVj*SigmaVj/j);

其中SigmaVjTj=2660200
SigmaVj=2564
SigmaTj=5500
j=5
按说计算后应当为VTk= - 5.609872255,实际调试中我用如下语句
PrintChar(24,60,(unsigned char)VTk/1000000+48,1);
PrintChar(30,60,(unsigned char)VTk%1000000/100000+48,1);       
PrintChar(36,60,(unsigned char)VTk%100000/10000+48,1);
PrintChar(42,60,(unsigned char)VTk%10000/1000+48,1);
PrintChar(48,60,(unsigned char)VTk%1000/100+48,1);
PrintChar(54,60,(unsigned char)VTk%100/10+48,1);
PrintChar(60,60,(unsigned char)VTk%10+48,1);       
把结果打印到LCD,值为000,0122

实在是搞不出来了,向各位高手求救,Help~
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
16条回答
Sullivan
2020-01-31 06:21
问题没解决,觉都睡不安稳。5点半起床接着干,终于解决了。
总结如下:

补充,j 的类型是unsigned char.

VTk=(float)(SigmaVjTj-SigmaVj*SigmaTj/j)/(SigmaVj2-SigmaVj*SigmaVj/j);
这行计算会影响精度,精度损失在SigmaTj/j和SigmaVj/j。应当改成
VTk=(SigmaVjTj-(float)SigmaVj*SigmaTj/j)/(SigmaVj2-(float)SigmaVj*SigmaVj/j);
计算之前先把unsigned long强制转换为float,每一段表达式只转换一个变量即可,与之相关的变量会自动被转换为float型。
因为这里unsigned long一定是非负的,强制转换float时没有问题。

调试时的主要问题出在我的打印语句上。
打印之前将float强制类型转换为unsigned long时,非负数可以直接取整转换,float为负时,则由于补码的原因,转换后的数据不再是所期望的数据。因此,LCD上的显示是错误的,这导致了我走了弯路,但VTk这个float变量的计算值是正确的。因此,VTk可以继续进行后面的计算。在最后显示的时候应该判断VTk的符号,变为非负后再显示。

晚上真的不能熬夜,一点效率都没有。这点东西干了3个小时也没有结果。早点睡觉起个大早30分钟就可以完成。
谢谢【2楼】hongjie0216,提到了若不转化数据类型会对精度产生影响;
谢谢【4楼】millwood0,你对我的激励很有效。

一周热门 更多>