2015-05-06 22 views
7

例如,C和C++编译器如何实现浮点数相等的决定?

float a = 1.0; 
float b = 1.2; 

puts(a == b? "equal": "not equal"); 

是否编译器处理它bitwisely或通过一些其他的方法呢?

(我知道这是不是一个好的选择通过决定浮点数的平等“==”,我只是想知道如何编译涉及这种情况。)

+1

按位和按值的区别是什么?当然它们对于浮点数是相同的 –

+0

@EdHeal好了,问题被编辑 – Wizmann

+5

所有浮点数都以** IEEE-754浮点格式**存储。它们是** 32位**(单精度浮点)或** 64位**(双精度浮点)。意思是根据内存中的位,每个浮点数都有一个等值整数。编译器以与整数等效大小相同的方式处理它。请参阅:[**浮点指南 - 程序员应该知道的内容... **](http://floating-point-gui.de/) –

回答

5

一般的完整答案是根据IEEE 754规范比较浮点数。

具体回答你的问题,大部分时间两个浮点数字进行比较逐位,只有少数例外情况:

  • 正负零被视为相等
  • NaN被认为不等于一切,甚至为NaN本身
  • 次归可以比较等于零,并且在某些操作模式等次归(如“刷新次归到零”),比这些前
  • 其他使用常规的按位比较
+3

......当然,除非系统不使用IEEE浮点(例如,某些IBM大型机仍然不支持,至少通常不少GPU)。 –

+1

C++不需要IEEE754(虽然[有一个静态变量,您可以检查ieee754是否在使用中](http://stackoverflow.com/questions/5777484/how-to-check-if-c-compiler -uses-IEEE-754-浮点标准))。 –

1

我假设你在编译完程序之后,它是如何比较两个浮点数的。漂浮物的存储方式非常独特。它被存储的符号,指数和分数如所见here。因此,除非绝对平等,否则程序会将1和1.000000000001视为不同。要检查它们是否几乎等于,您可以使用以下命令:

bool AlmostEqualRelativeOrAbsolute(float A, float B, 
      float maxRelativeError, float maxAbsoluteError) 
{ 
    if (fabs(A - B) < maxAbsoluteError) 
     return true; 
    float relativeError; 
    if (fabs(B) > fabs(A)) 
     relativeError = fabs((A - B)/B); 
    else 
     relativeError = fabs((A - B)/A); 
    if (relativeError <= maxRelativeError) 
     return true; 
    return false; 
} 

的代码是从here获得,你可能想了解更多在现场。

3

gcc和clang使用UCOMISS x86/x64指令。

来源:tried it-O3并检查了装配输出。

+5

更一般地说,如果体系结构具有硬件支持(如x86,x86-64和ARM),则编译器会生成特定体系结构的指令,以便比较浮点数,否则它会发出一系列指令来实现所需的行为由所使用的浮点标准,几乎总是IEEE-754。 –