C++ C和C++;编译器实现浮点数相等的判定?

C++ C和C++;编译器实现浮点数相等的判定?,c++,c,floating-point-precision,C++,C,Floating Point Precision,比如说, float a = 1.0; float b = 1.2; puts(a == b? "equal": "not equal"); 编译器是按位处理还是用其他方法处理 (我知道用“==”来判断浮点数是否相等不是一个好选择,我只是想知道编译器如何处理这种情况。)我假设你的意思是,在编译程序后,它如何比较两个浮点数。浮点数的存储方式非常独特。它通过符号、指数和分数存储,如图所示。因此,除非绝对相等,否则程序甚至会将1和1.000000000001视为不同。要检查它们是否几乎相等,可以使

比如说,

float a = 1.0;
float b = 1.2;

puts(a == b? "equal": "not equal");
编译器是按位处理还是用其他方法处理


(我知道用“==”来判断浮点数是否相等不是一个好选择,我只是想知道编译器如何处理这种情况。)

我假设你的意思是,在编译程序后,它如何比较两个浮点数。浮点数的存储方式非常独特。它通过符号、指数和分数存储,如图所示。因此,除非绝对相等,否则程序甚至会将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;
}
bool AlmostEqualRelativeOrAbsolute(浮点A、浮点B、,
浮点maxRelativeError,浮点maxAbsoluteError)
{
if(晶圆厂(A-B)晶圆厂(A))
相对误差=晶圆厂((A-B)/B);
其他的
相对误差=晶圆厂((A-B)/A);
如果(relativeErrorgcc和clang使用x86/x64指令


来源:使用
-O3
检查组件输出。

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

为了明确回答您的问题,大多数情况下,两个浮点数是按位比较的,但有一些例外情况:

  • 正零和负零被认为是相等的
  • NaN被认为不等于一切,甚至不等于NaN本身
  • 在某些操作模式下,次正常值可与等于零和其他次正常值进行比较(例如,“将次正常值刷新为零”)
  • 除这些例外情况外,还使用常规的按位比较

按位和按值之间的区别是什么?浮点数肯定是相同的。所有浮点数都以IEEE-754浮点数格式存储。它们是32位(单精度浮点数)或64位(双精度浮点数)。表示基于内存中的位,每个浮点数都有一个等效的整数。编译器处理它的方式与处理等效大小的整数的方式相同。请参阅:@DavidC.Rankin,但+0/-0除外(不同的位模式)无论如何..和NaN都是不可排序的。也就是说,有一种特殊情况是不同的位模式相等,而一些相同的位模式不相等..但是好的链接:-)我被纠正了。谢谢你指出这些情况。@EdHeal:+0=−两者都不等于零−1.浮点数上的相等是精确定义的,它只会产生经常让新手感到惊讶的结果。基本上,除非你知道自己在做什么,否则这不是一个好主意。
1.0+1.0==2.0
总是成立;
1.0/2.0-1.0/4.0==1.0/4.0
也成立;
1.0/3.0+1.0/3.0==2.0
不成立。更一般地说来,th如果体系结构有硬件支持,例如x86、x86-64和ARM,则e编译器会生成一条体系结构特定的指令,用于比较浮点数,否则它会发出一系列指令,实现使用中的浮点标准所需的行为,几乎总是IEEE-754……当然,当该系统不使用IEEE浮点(例如,一些IBM主机仍然没有,相当多的GPU不,至少通常)。C++不需要IEEE74(虽然)。