浮点行为不正确

Incorrect floating point behavior

本文关键字:不正确      更新时间:2023-10-16

当我在支持软件浮点模拟(禁用硬件浮点)的32位powerpc内核中运行以下C++程序时,我得到了不正确的条件求值。有人能告诉我这里潜在的问题是什么吗?

#include <stdio.h>
int main() {
   int newmax = 1;
   if ((newmax + 0.0) > 256) {
       printf("nShouldn't be heren");
   } else {
       printf("nShould be heren");
   }
}

编译:

powerpc-linux-g++ -msoft-float -c floating.cxx
powerpc-linux-g++  -o floating floating.o

目标系统输出:

[linux:/]$ ./floating
Shouldn't be here

链接时也应该指定-msoft-floot给我们一个带有-S标志的disassembly:powerpc-linux-g++-msoft-foat-c floating.cxx-S-o floating.S

首先,为什么禁用硬件浮点?

由于这种类型,可能会按不正确的顺序执行强制转换。

(double)1 = 0x3FF0000000000000
(float) 1 = 0x3F800000

这是你的情况。

if ((newmax + 0.0) > 256)

在您的情况下:1) newmax铸造为浮动或双重;2) 加0.0;3) 返回到内部的获取值

它取决于您的机器,但int通常是32位值。要检查它,您可以使用:

int i;
printf("%d", sizeof(i));

不管怎样,回到你的问题,在计算值转换成int后,你会得到一个大的正数。在你的情况下,我会打印它/或不是与0x100进行比较,而是与进行比较

0x3F800000,0x3F0000000000000,0x3F00000

要弄清楚发生了什么,但拆卸是最好的选择。

也许这没什么帮助,但这只是我的想法,发生了什么。

这可能是从编译器错误到汇编程序错误再到链接器错误再到内核错误的任何错误。正如其他人已经指出的那样:如果使用-S选项提供编译输出,编译器错误(这是最有可能导致此错误的原因)可以得到验证(或排除)。如果不是编译器错误,那么浮点模拟的内核错误将是下一个可能的问题来源。

代码newmax+0.0中的语句以浮点或双精度生成结果,但会与整数值进行比较。

从而产生这种误差。

试试这个,

int i=1;
printf("%d",(i+0.0));

无论i的值是多少,你每次都会得到一个结果0。然而,

int i=1;
printf("%f",(i+0.0));

这将产生1.0000