C ++中的暗角浮点行为 [英] Dark-corners floating-point behavior in C++

查看:75
本文介绍了C ++中的暗角浮点行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++标准是否在

例外期间指定浮点数的行为。 (特殊的浮点数,不是

除外)条件?


例如:


double a = 1.0 / 0.0; //什么是价值?无限?

双b = 0.0 / 0.0; // b的价值是多少? NaN?


库中的溢出/下溢情况怎么样? HUGE_VAL是否总是一个

定义的常量?

#include< cmath>

使用命名空间std;


double c = pow(1e100,1e100); // c的值是多少?

double d = pow(0.5,1e100); // ef d的值是多少?

Does the C++ standard specify the behavior of floating point numbers during
"exceptional" (exceptional with respect to floating point numbers, not
exceptions) conditions?

For example:

double a = 1.0 / 0.0; // What is the value of a? Infinity?
double b = 0.0 / 0.0; // What is the value of b? NaN?

What about overflow/underflow conditions in the library? Is HUGE_VAL always a
defined constant?

#include <cmath>
using namespace std;

double c = pow(1e100, 1e100); // What is the value of c?
double d = pow(0.5, 1e100); // What is the value ef d?

推荐答案

2005年9月7日星期三05:32:17 GMT,Dave Rahardja< as * @ me.com>写在

comp.lang.c ++:
On Wed, 07 Sep 2005 05:32:17 GMT, Dave Rahardja <as*@me.com> wrote in
comp.lang.c++:
C ++标准是否在
例外期间指定浮点数的行为。 (特殊的浮点数,而不是例外情况)条件?

例如:

double a = 1.0 / 0.0; //什么是价值?无限?
双b = 0.0 / 0.0; // b的价值是多少?喃?


以上两种行为都是明确未定义的。

没有要求或指定值,没有。

库中的溢出/下溢情况怎么样? HUGE_VAL总是定义为常量吗?


HUGE_VAL是< math.h> /< cmath>中的必需宏。它扩展为

正双精度表达式,不一定代表

浮点数。意图是,如果

浮点类型具有这样的表示,它是可以以双精度或正无穷大表示的最大可能值。 。

#include< cmath>
使用命名空间std;

double c = pow(1e100,1e100); // c的价值是多少?


假设结果太大而无法用双精度表示,

他的一个应该导致HUGE_VAL,并且errno设置为ERANGE。

double d = pow(0.5,1e100); // ef d的值是多少?
Does the C++ standard specify the behavior of floating point numbers during
"exceptional" (exceptional with respect to floating point numbers, not
exceptions) conditions?

For example:

double a = 1.0 / 0.0; // What is the value of a? Infinity?
double b = 0.0 / 0.0; // What is the value of b? NaN?
The behavior of both of the above is just plain undefined. There is
no requirement or specification of a value, there is none.
What about overflow/underflow conditions in the library? Is HUGE_VAL always a
defined constant?
HUGE_VAL is a required macro in <math.h>/<cmath>. It expands to a
positive double constant expression not necessarily representable in a
float. The intent is that it be the largest possible value that can
be held in a double, or a representation of positive infinity, if the
floating point type has such a representation.
#include <cmath>
using namespace std;

double c = pow(1e100, 1e100); // What is the value of c?
Assuming that the result is too large to be represented in a double,
his one should result in HUGE_VAL, and errno is set to ERANGE.
double d = pow(0.5, 1e100); // What is the value ef d?




再次假设对double的范围有限制,这样这个

下溢到0,返回值为0.0,errno可能是也可能不是

设置为ERANGE。


但是不要混淆库函数,它们已完全定义

行为,当使用任何算术类型的内置

算术运算符时出现溢出或下溢,无论是浮点还是

有符号整数类型。后者只有明确的未定义行为。

除以0,即使是无符号整数类型,也是未定义的

行为。


没有< math.h> /< cmath>当在参数

类型中表示可传递的参数时,允许函数产生

未定义的行为。如果参数超出函数的范围,例如在[-1,+ 1]到acos()范围之外的

参数,则

实现 - 返回定义的值,并将errno设置为EDOM。


如果函数的结果在返回类型中无法表示,

函数主要返回HUGE_VAL或-HUGE_VAL并将errno设置为

ERANGE在幅度溢出时,0和errno可能设置为ERANGE。


-

Jack Klein

主页: http://JK-Technology.Com

常见问题解答

comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html

comp.lang.c ++ < a rel =nofollowhref =http://www.parashift.com/c++-faq-lite/target =_ blank> http://www.parashift.com/c++-faq-lite/

alt.comp.lang.learn.c-c ++
http://www.contrib.andrew.cmu.edu/~a...FAQ- acllc.html



Again assuming limitations on the range of a double, so that this
underflows to 0, the return will be 0.0, errno might or might not be
set to ERANGE.

But don''t confuse library functions, which have fully defined
behavior, with overflow or underflow when using the build-in
arithmetic operators on any arithmetic type, be it floating point or
signed integer types. The latter has just plain undefined behavior.
Division by 0, even with unsigned integer types, is also undefined
behavior.

None of the <math.h>/<cmath> functions are allowed to produce
undefined behavior when passed arguments representable in the argument
type. If the arguments are out of range for the function, such as an
argument outside the range of [-1,+1] to acos(), an
implementation-defined value is returned and errno is set to EDOM.

If the result of the function is not representable in the return type,
the functions mostly return HUGE_VAL or -HUGE_VAL and set errno to
ERANGE on magnitude overflow, and 0 with errno possible set to ERANGE.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html


首先:向您发送第一个版本的应用程序,而不是

NG。


如果您的编译器遵循浮动标准

您可以通过包括< limits>来检查然后测试一致性

使用:

numeric_limits< float> :: is_iec559


如果符合标准,应该得到以下结果:
First: appologies for sending the first version to you instead of the
NG.

If your compiler follows the float standard
Which you can check by including <limits> then test for conformance
using:
numeric_limits<float>::is_iec559

The following should result if it follows the standard:
double a = 1.0 / 0.0; //什么是价值?无穷?
一个错误,因为编译器发现除数为0时,它将b / b试图将1.0 / 0.0转换为常数。

忽略:+无穷大(无穷大)保持标志)

double b = 0.0 / 0.0; // b的价值是多少?喃?
见上面的评论。

结果将是:不确定

库中的溢出/下溢情况怎么样? HUGE_VAL总是定义为常量吗?
这种错误通常会被困在处理器上。

有一些特定于操作系统的解决方案可以解决这些错误。

double c = pow(1e100,1e100) ); // c的价值是多少?
+ Infinity

double d = pow(0.5,1e100); // ef d的值是多少?
double a = 1.0 / 0.0; // What is the value of a? Infinity? An error since the compiler should discover a division by 0 when it
attempts to turn 1.0/0.0 into a constant.
Ignoring that: +Infinity (infinity keeps sign)
double b = 0.0 / 0.0; // What is the value of b? NaN? See comment above.
The result would be: Indetermined
What about overflow/underflow conditions in the library? Is HUGE_VAL always a
defined constant? This kind of error generally gets trapped at the processor.
There are OS specific solutions to get at these errors.
double c = pow(1e100, 1e100); // What is the value of c? +Infinity
double d = pow(0.5, 1e100); // What is the value ef d?



0


根据操作系统的工作原理,所有4次计算都将导致
可以使用操作系统特定功能恢复的各种错误。


0

And depending on how the OS works all 4 calculations will result in
various errors that can be recoved using os specific functions.


2005年9月7日星期三02:38:39 -0500,杰克Klein< ja ******* @ spamcop.net>写道:
On Wed, 07 Sep 2005 02:38:39 -0500, Jack Klein <ja*******@spamcop.net> wrote:
double c = pow(1e100,1e100); // c的值是什么?
double c = pow(1e100, 1e100); // What is the value of c?



假设结果太大而无法用double表示,
他的那个应该导致HUGE_VAL,并且errno被设置到ERANGE。



Assuming that the result is too large to be represented in a double,
his one should result in HUGE_VAL, and errno is set to ERANGE.




感谢您的回复。有没有一种可移植的方法来检测这些条件,即使在它们发生之后也是如此?


我对errno的麻烦是它只能使用在单线程

应用程序中。我的应用程序在某些时候几乎总是多线程的。


像_matherr()这样的库中有一些钩子允许我陷入这些错误的

,但是我怀疑这些挂钩不属于标准库。

我是对的吗?


-dr



Thanks for your reply. Is there a portable way to detect these conditions at
run-time, even after they have happened?

My trouble with errno is that it is usable only in a single-threaded
application. My applications are almost always multithreaded at some point.

There are hooks in some libraries like _matherr() that allow me to trap for
these errors, but I suspect those hooks are not part of the standard library.
Am I right?

-dr


这篇关于C ++中的暗角浮点行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆