在c++中,是否保证在浮点数上为真?

时间:2021-08-01 17:07:10

In C++, do I have a guarantee that, for any given float a and float b, one and only one of a < b, a == b and a > b is true?

在c++中,我是否有一个保证,对于任何给定的浮点a和浮点b, a < b, a = b和> b中只有一个是正确的?

If this differs between compilers and platforms, I am interested in Visual C++ on x86.

如果编译器和平台之间存在差异,我对x86上的Visual c++感兴趣。

1 个解决方案

#1


75  

No.

不。

It's enough for either a or b to be NaN for each of a < b, a == b and a > b to be false.

对于a或b来说,对于a < b, a = b和a > b都足够为NaN。

If both a and b are non-NaN then exactly one of a < b, a == b or a > b has to be true.

如果a和b都是非nan,那么a < b, a == b或> b必须为真。

In complement, this answer tells you how you can get a NaN value in C++ (there are several NaN values, that can be distinguished by inspecting their representations; they are all different from each other because NaN is never equal to anything,) and how you can test whether a value is a NaN (an idiomatic test to see if a variable x is a NaN is x != x, and indeed std::isnan() is often implemented this way, but some programmers who will have to read your code may be confused by it).

在补语中,这个答案告诉您如何在c++中获得NaN值(有几个NaN值,可以通过检查它们的表示来区分它们;他们都不同,因为南不等于什么,),以及如何测试值是否是一个南(一个惯用的测试,看看一个变量x是一个南! = x,事实上std::isnan()通常是实现这种方式,但一些程序员必须阅读你的代码可能会困惑)。

And then, if a and b are the results of previous computations, there is the problem of excess precision. See this article for a discussion in C. The C99 standard solved the problem by making rules explicit for where excess precision could and could not occur, but despite C++ more or less inheriting these rules by deferring to the C standard for the definition of FLT_EVAL_METHOD in cfloat, in practice C compilers take the rules more seriously than C++ compilers. For instance GCC implements the rules for C when compiling with -std=c99, and in this context you can rely on the property to hold, but as of this writing GCC does not implement these rules when used as a C++ compiler.

然后,如果a和b是之前计算的结果,就存在精度过高的问题。看到这篇文章的讨论C C99标准解决了这个问题通过规则明确精度可能和不可能出现过剩,但尽管c++或多或少地继承这些规则通过延迟的C标准的定义在cfloat FLT_EVAL_METHOD,在实践中C编译器更认真地对待规则比c++编译器。例如,GCC在使用-std=c99编译时实现了C的规则,在这种情况下,您可以依赖属性来保持,但是在编写本文时,当使用c++编译器时,GCC并没有实现这些规则。

#1


75  

No.

不。

It's enough for either a or b to be NaN for each of a < b, a == b and a > b to be false.

对于a或b来说,对于a < b, a = b和a > b都足够为NaN。

If both a and b are non-NaN then exactly one of a < b, a == b or a > b has to be true.

如果a和b都是非nan,那么a < b, a == b或> b必须为真。

In complement, this answer tells you how you can get a NaN value in C++ (there are several NaN values, that can be distinguished by inspecting their representations; they are all different from each other because NaN is never equal to anything,) and how you can test whether a value is a NaN (an idiomatic test to see if a variable x is a NaN is x != x, and indeed std::isnan() is often implemented this way, but some programmers who will have to read your code may be confused by it).

在补语中,这个答案告诉您如何在c++中获得NaN值(有几个NaN值,可以通过检查它们的表示来区分它们;他们都不同,因为南不等于什么,),以及如何测试值是否是一个南(一个惯用的测试,看看一个变量x是一个南! = x,事实上std::isnan()通常是实现这种方式,但一些程序员必须阅读你的代码可能会困惑)。

And then, if a and b are the results of previous computations, there is the problem of excess precision. See this article for a discussion in C. The C99 standard solved the problem by making rules explicit for where excess precision could and could not occur, but despite C++ more or less inheriting these rules by deferring to the C standard for the definition of FLT_EVAL_METHOD in cfloat, in practice C compilers take the rules more seriously than C++ compilers. For instance GCC implements the rules for C when compiling with -std=c99, and in this context you can rely on the property to hold, but as of this writing GCC does not implement these rules when used as a C++ compiler.

然后,如果a和b是之前计算的结果,就存在精度过高的问题。看到这篇文章的讨论C C99标准解决了这个问题通过规则明确精度可能和不可能出现过剩,但尽管c++或多或少地继承这些规则通过延迟的C标准的定义在cfloat FLT_EVAL_METHOD,在实践中C编译器更认真地对待规则比c++编译器。例如,GCC在使用-std=c99编译时实现了C的规则,在这种情况下,您可以依赖属性来保持,但是在编写本文时,当使用c++编译器时,GCC并没有实现这些规则。