C 嵌入式系统中的浮点错误
在兔子微控制器上。。 1. 通过将小时转换为现有值并存储在同一寄存器中,我每秒递增f1C 嵌入式系统中的浮点错误,c,embedded,unsigned-integer,C,Embedded,Unsigned Integer,在兔子微控制器上。。 1. 通过将小时转换为现有值并存储在同一寄存器中,我每秒递增f1 void main() { float f1; int i; f1 = 4096; // Assume that I am simulating a one second through each iteration of the following loop for(i = 0; i < 100; i++) { f1 += 0.00027
void main()
{
float f1;
int i;
f1 = 4096;
// Assume that I am simulating a one second through each iteration of the following loop
for(i = 0; i < 100; i++)
{
f1 += 0.000278; // f1 does not change from 4096
printf("\ni: %d f1: %.06f", i, f1);
}
}
f1+=1/3600;应为f1+=1.0f/3600.0f
如果执行整数除法,则结果也将是整数。第一个问题是单精度32位二进制浮点仅适用于十进制中约6位有效数字。因此,如果从4096.00开始,则不能向值中添加任何小于.01的值。使用双精度将在一定程度上提高结果 使用浮点通常是不必要和不合适的,在没有FPU的处理器上使用浮点非常昂贵,尤其是在8位处理器上。此外,在任何情况下,以1.0f/3600.0f小时表示的1秒的文字近似值都会引入显著的累积误差。您最好将时间存储为整数秒,并在需要显示或输出时转换为小时 第二个问题不太清楚,但可能是浮点的Rabbit编译器实现的问题,也可能是printf实现中的%f格式说明符的问题。检查编译器文档中的ISO符合性声明-可能有限制-尤其是在浮点上。同样,您可能会发现使用双精度标记可以解决问题-尤其是严格地说,这是符合ISO标准的实现中%f格式说明符所期望的类型。正如我所说,在这样一个目标上,您最好完全避免使用浮点
注意,如果您使用的是Rabbit的动态C编译器,那么您应该清楚动态C不是符合ISO标准的C编译器。它是一种专有的类C语言,与C语言非常相似,会引起很大的混乱!具体来说,它不支持双精度双浮点。关于第二个问题:我的机器上的输出是L1:4000000000F1:4000000000.000000,而不是-4000000000.000000。建议1您的编译器有故障,2发布的代码不是真实代码,或者3外部的chance void main应该是int mainvoid。要记住的简单规则是float最多可以存储7个精确数字。您的增量太小,它需要一个至少可以存储8位数字的类型。您将需要双倍或缩放3600,以便使用整数类型。1 Code posted是实际运行的代码及其输出。2我相信嵌入式系统并不总是需要int mainvoid,因为没有主机操作系统监控此程序返回代码。我在系统中没有双重数据类型。如果我增加整数,那么它们加起来很快,可能会在某个点滚动。如果可能的话,我需要一种方法让这个数字永远增长。你的系统上根本没有浮点硬件——它都是在带有整数运算的库中模拟的。考虑大类型整数运算的缩放。还考虑手臂皮质M4…他们现在从各种各样的供应商那里买来的东西都很便宜。+1是的,这是问题最初发布时的一个关键问题——尽管后来经过编辑以消除特定的问题,然后海报修复了您指出的问题并不会使您的答案无效。
void main()
{
unsigned long L1;
int temp;
float f1;
L1 = 4000000000; // four billion
f1 = (float)L1;
// Now print both
// You see that L1: 4000000000 while f1: -4000000000.000000
printf("\nL1: %lu f1:%.6f", L1, f1);
}