473,399 Members | 3,038 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

Dark-corners floating-point behavior in C++

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?
Sep 7 '05 #1
12 3776
On Wed, 07 Sep 2005 05:32:17 GMT, Dave Rahardja <as*@me.com> wrote in
comp.lang.c++:
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?


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
Sep 7 '05 #2
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; // 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

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

Sep 7 '05 #3
On Wed, 07 Sep 2005 02:38:39 -0500, Jack Klein <ja*******@spamcop.net> wrote:
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.


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
Sep 7 '05 #4
Dave Rahardja wrote:
My trouble with errno is that it is usable only in a single-threaded
application. My applications are almost always multithreaded at some point.


[DISCLAIMER: NON STANDARD SINCE THE STANDARD DOESN'T ADDRESS THREADS]

The implementations that I've seen (MSVC and G++) define errno in a
multithreaded environment as a macro which gives thread-specific error info.

i.e. [SAMPLE ONLY, NOT ACTUAL IMPLEMENTATION]

int *thread_specific_errno();
#define errno (*thread_specific_errno())
Sep 7 '05 #5
ve*********@hotmail.com wrote:
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; // 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)


It's not an error. The result, as you say, is +infinity.

double b = 0.0 / 0.0; // What is the value of b? NaN?
See comment above.
The result would be: Indetermined


No. Again, it's not an error. The result is NaN (not a number).
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.


Under IEC 60559 (the successor to IEC 559, which is the basis for the
name used in numeric_limits) the result of an overflow is a suitably
signed infinity. The result of an underflow is a denormal value if the
compiler supoprts them, or a suitably signed zero.

double c = pow(1e100, 1e100); // What is the value of c?
+Infinity


If the value is too large for double to handle, which is usually the
case. But it isn't required.

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


If the value is too small for double to handle, which is usually the
case. But it isn't required.

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


No, under IEC 60559 these are not errors. They lead to floating-point
exceptions, which are nothing like C++ exceptions. The default behavior
is to continue the computation, with (mostly) well-defined rules for
what happens when code manipulates NaNs and infinities. You then test at
the end to see whether you got a NaN or an infinity, in which case you
conclude that you screwed up, or whether one or more of the exception
sticky bits is set, in which case you conclude that you might have
screwed up.

C99 incorporates most of this in the language and library. The C++ TR1
incorporates the library portions of C99, and C++0x will almost
certainly have all that C99 has in this area.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Sep 7 '05 #6
On Wed, 07 Sep 2005 11:24:39 -0500, Pete Becker <pe********@acm.org> wrote:
Under IEC 60559 (the successor to IEC 559, which is the basis for the
name used in numeric_limits) the result of an overflow is a suitably
signed infinity. The result of an underflow is a denormal value if the
compiler supoprts them, or a suitably signed zero.


So can we assume the behaviors you described if
std::numeric_limits<double>::is_iec559 == true?

-dr
Sep 8 '05 #7
Dave Rahardja wrote:
On Wed, 07 Sep 2005 11:24:39 -0500, Pete Becker <pe********@acm.org> wrote:

Under IEC 60559 (the successor to IEC 559, which is the basis for the
name used in numeric_limits) the result of an overflow is a suitably
signed infinity. The result of an underflow is a denormal value if the
compiler supoprts them, or a suitably signed zero.

So can we assume the behaviors you described if
std::numeric_limits<double>::is_iec559 == true?


is_iec559 asserts that the implementation conforms to the IEC 559
standard. IEC 60559 is the same thing.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Sep 8 '05 #8
On Thu, 08 Sep 2005 10:02:29 -0500, Pete Becker <pe********@acm.org> wrote:
Dave Rahardja wrote:
On Wed, 07 Sep 2005 11:24:39 -0500, Pete Becker <pe********@acm.org> wrote:

Under IEC 60559 (the successor to IEC 559, which is the basis for the
name used in numeric_limits) the result of an overflow is a suitably
signed infinity. The result of an underflow is a denormal value if the
compiler supoprts them, or a suitably signed zero.

So can we assume the behaviors you described if
std::numeric_limits<double>::is_iec559 == true?


is_iec559 asserts that the implementation conforms to the IEC 559
standard. IEC 60559 is the same thing.


Thanks Pete!

Just got my hands on a copy of IEEE 754. How is IEC 559/60559 different from
the IEEE standards?

-dr
Sep 9 '05 #9
> Just got my hands on a copy of IEEE 754. How is IEC 559/60559 different from
the IEEE standards?


They are the same standard only classified by a different organisation.

Sep 9 '05 #10

Pete Becker wrote:
ve*********@hotmail.com wrote:
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; // 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)


It's not an error. The result, as you say, is +infinity.


Please read again. I point out that the compiler would probably have a
fit as it would try to replace 1.0/0.0 with a constant and generate a
compile time error for division by 0.

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


See comment above.
The result would be: Indetermined


No. Again, it's not an error. The result is NaN (not a number).


The result is indetermined not NaN seeing that it can be any number.
This is one of the few situations you do not get a NaN returned
(although a lot of material on the net assumes you get one) the other
situation I can come up with would trying to divide infinity by
infinity.

Sep 9 '05 #11
On 9 Sep 2005 03:14:44 -0700, "ve*********@hotmail.com"
<ve*********@hotmail.com> wrote:
>
>
>>double b = 0.0 / 0.0; // What is the value of b? NaN?
>
> See comment above.
> The result would be: Indetermined
>


No. Again, it's not an error. The result is NaN (not a number).


The result is indetermined not NaN seeing that it can be any number.
This is one of the few situations you do not get a NaN returned
(although a lot of material on the net assumes you get one) the other
situation I can come up with would trying to divide infinity by
infinity.


Actually, not if your compiler (and library) are IEEE-754 compliant. From the
standard:

7.1 Invalid Operation

The invalid operation exception is signaled if an operand is invalid for the
operation on to be performed. The result, when the exception occurs without a
trap, shall be a quiet NaN (6.2) provided the destination has a floating-point
format. The invalid operations are

1) Any operation on a signaling NaN (6.2)

2) Addition or subtraction—magnitude subtraction of infinites such as, (+inf)
+ (-inf)

3) Multiplication—0 * inf

4) Division—0/0 or inf/inf

5) Remainder— x REM y, where y is zero or x is infinite

6) Square root if the operand is less than zero

7) Conversion of a binary floating-point number to an integer or decimal
format when overflow, infinity, or NaN precludes a faithful representation in
that format and this cannot otherwise be signaled

8) Comparison by way of predicates involving < or >, without ?, when the
operands are unordered (5.7, Table 4)

Item 4 specifies that 0/0 results in a NaN if not otherwise trapped.

-dr
Sep 9 '05 #12
ve*********@hotmail.com wrote:

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)
It's not an error. The result, as you say, is +infinity.

Please read again. I point out that the compiler would probably have a
fit as it would try to replace 1.0/0.0 with a constant and generate a
compile time error for division by 0.


It should not generate a compile time error under IEC 60559. It should
use the value +infinity.


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

See comment above.
The result would be: Indetermined

No. Again, it's not an error. The result is NaN (not a number).

The result is indetermined not NaN seeing that it can be any number.


No, that's the classic case where NaN is appropriate. Look it up.
This is one of the few situations you do not get a NaN returned
(although a lot of material on the net assumes you get one) the other
situation I can come up with would trying to divide infinity by
infinity.


Which also produces a NaN.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Sep 11 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Philippe Meunier | last post by:
Hi, I am using the .NET toolbar with VB.NET 2003. My toolbar uses icons images that are actually PNG files and uses alpha blending on it. So to make alpha blending work correctly with the...
5
by: Aaron Harvey | last post by:
I don't know if anyone knows anything about programming C++ to do mysql database manipulation, but here it goes anyway ... I'm getting desperate to find a solution. I'm going absolutely freakin...
28
by: John Bailo | last post by:
Funny, how Bill Gate uses the Deutsches Bank and Barron's to defraud people and try to wreck his competitors ( he can't ). For example, ...
5
by: Rudi Hausmann | last post by:
Hi! I want to "paint" some blocks with text in it. As the box can overlap I want the text to be transparent using opacity. Though, the text shall stay well visible. Here is what I produced so...
3
by: virgil46 | last post by:
How do I for instance, fade the background color from dark gold at the top of the page to a light gold, by the time it gets to the bottom of the page?
6
by: Rob | last post by:
I would like to show dark fonts (so that the text is readable and not greyed out) in a text box, however, I do Not want the text box to be Enabled, because I do not want the text box to ever have...
0
by: medin0065 | last post by:
dark crusade patch 1.2 http://cracks.00bp.com F R E E
0
by: carlwuhwdmckay | last post by:
dark crusade 1.11 patch http://cracks.00bp.com F R E E
0
by: leoniaumybragg | last post by:
dark crusade patch http://cracks.00bp.com F R E E
2
by: zubair1 | last post by:
Hi, I just recently downloaded Dark GDK from Microsoft's Website i was using Visual Studio 2005 when i was installing the Dark GDK it said it didn't find the C++ Compiler and asked me if i want...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.