我有一份用C语言编写的代码,旨在为16位微控制器使用。该代码主要进行了大量的浮点数运算。
这些算术运算在结果为正数时工作正常,但在减法中,如果期望的结果是负数,则会得到零。
result = 0.005 - 0.001; Is correctly computed as 0.004
result = 0.001 - 0.005; Is always zero.
为什么浮点数会发生这种行为?
我有一份用C语言编写的代码,旨在为16位微控制器使用。该代码主要进行了大量的浮点数运算。
这些算术运算在结果为正数时工作正常,但在减法中,如果期望的结果是负数,则会得到零。
result = 0.005 - 0.001; Is correctly computed as 0.004
result = 0.001 - 0.005; Is always zero.
为什么浮点数会发生这种行为?
result = 0.005 - 0.001;
result = -result;
result = 0.002 - 0.001;
result = 0.002 - 0.002;
result = 0.002 - 0.003;
result = 0.001 - 0.002;
result = 0.001 - 0.003;
result = 0.001 - 0.004;
result = 0.005 - 0.001; // 0.004
result = -result; // 0.000
result = 0.002 - 0.001; // 0.001
result = 0.002 - 0.002; // 0.000
result = 0.002 - 0.003; // 0.000
result = 0.001 - 0.002; // 0.000
result = 0.001 - 0.003; // 0.000
result = 0.001 - 0.004; // 0.000
我不确定我完全理解了,但我会尽力而为。Adriaan,"result" 的数据类型是 float,即 32 位表示(单精度)。我使用 CAN 作为系统接口,因此我将结果乘以 1000 并通过 CAN 总线发送。如果它是一个负数,比如 -0.003,那么我期望在 CAN 消息中得到 FF FD。我没有调试器。
int main(void) {
float w = -0.003;
int x = (int)(w * 1000);
int y = -3;
int z = -32768;
// Show us you code here for printing x, y and z.
return 0;
}
微控制器是否具有浮点数硬件?可能没有;微控制器通常不具备此功能。因此,这可能是浮点运算软件实现中的错误或限制。查找文档,如果有源代码,请阅读源代码。
你是否尝试将0.001-0.005的结果打印成5个字符的字段?如果是,结果将显示为四舍五入为0.0。
您能提供更多上下文吗?在这个例子中,评估可能是由编译器完成的,因为两个常量在编译时已知。'result'的类型是什么?(即IEEE-754 half、single还是double?)您如何评估这个问题?使用调试器、if语句还是printf?我之所以问这个问题,是因为可能会有一个误导。例如,如果您使用printf格式不正确,您可能只看不到减号。当您查看二进制表示(即通过printf("%lx", result)(如果它是32位))并检查符号位时,请注意。
这不是固有的C语言问题,所以问题存在于您没有提到的以下几点:
可能是你没有展示从浮点数转换为整数的类型转换吗?