Hi people
I continue to work in the tutorial for lcc-win32, and started to try to
explain the floating point flags.
Here is the relevant part of the tutorial. Since it is a difficult part,
I would like your expert advise before I publish any serious nonsense.
Any comments are welcome, style, organization, hard errors, etc.
Thanks in advance
jacob
-------------------------------------------------------------------
Using the floating point environment
------------------------------------
The C standard specifies a type fenv_t that “refers collectively to any
floating-point status flags and control modes supported by the
implementation.”
This environment has two special parts, the “floating point status
flags” that are set by the operations the program performs, and the
“control flags” that changes how the hardware does the operations, for
instance the rounding mode, etc.
The status flags
----------------
The standard requires at least the following flags:
FE_DIVBYZERO A division by zero has occurred
FE_INEXACT The last operation had to be rounded
FE_INVALID An invalid operation was attempted
FE_OVERFLOW The result of an operation was too big to be represented
FE_UNDERFLOW The result of an operation was too small to be represented
In addition to this standard flags, lcc-win32 provides:
FE_DENORMAL The result of the last operation was a denormal number
FE_STACKFAULT The floating point stack has overflowed.
The denormal flag means that a loss of precision is certain, the number
is too small to be represented. The stack fault flag means that
lcc-win32 generated bad code, since all floating point operations should
balance the floating point stack. If you ever test positive for this
flag, do not hesitate to send me a bug report!
In general, the floating point flags can be queried by the program to
know if the last operation did complete without problems. Here is a
small example to show you how this works:
/* This program tests a division by zero */
#include <fenv.h>
#include <stdio.h>
int main(void)
{
double a=1,b=0;
feclearexcept(FE_DIVBYZERO);
a=a/b;
if (fetestexcept(FE_DIVBYZERO)) {
printf("You have divided by zero!\n");
}
return 0;
}
First we clear the flag that we are going to use using feclearexcept.
Then, we perform our operation and query if the flag is set using
fetestexcept.
Since we know that the flags are set but not cleared, the expression
could be very well be a much more complicated sequence of operations.
The above code would work the same, but we would loose the possibility
of knowing exactly which operation failed. This is in many cases not
very important, we could very well be interested that somewhere there
was a serious error, without bothering to investigate which operation
was that it failed.
Reinitializing the floating point environment
---------------------------------------------
Things can become messy, and you would like to reset everything to a
known state. The standard provides the macro FE_DFL_ENV, that represents
the address of the default environment, the one you started with. In
lcc-win32 this environment is stored in the __default_fe_env global
variable, so this macro is just:
#define FE_DFL_ENV (&__default_fe_env)
You can reset everything to its default state with:
fesetenv(FE_DFL_ENV);
The default environment in lcc-win32 has the following characteristics:
1) The rounding mode is set to round to nearest.
2) The precision of the FPU is set to full precision (80 bits)
3) All exceptions are masked, i.e. the result of invalid operations is a
NAN, not a trap.
--------------------------------------------------------------------------- 4 2807
In article <43***********************@news.wanadoo.fr>,
jacob navia <ja***@jacob.remcomp.fr> wrote: Hi people
I continue to work in the tutorial for lcc-win32, and started to try to explain the floating point flags.
Here is the relevant part of the tutorial. Since it is a difficult part, I would like your expert advise before I publish any serious nonsense.
Any comments are welcome, style, organization, hard errors, etc.
Thanks in advance
jacob -------------------------------------------------------------------
Using the floating point environment ------------------------------------
The C standard specifies a type fenv_t that ³refers collectively to any floating-point status flags and control modes supported by the implementation.²
This environment has two special parts, the ³floating point status flags² that are set by the operations the program performs, and the ³control flags² that changes how the hardware does the operations, for instance the rounding mode, etc.
The status flags ---------------- The standard requires at least the following flags: FE_DIVBYZERO A division by zero has occurred FE_INEXACT The last operation had to be rounded
Are you sure it is "the last operation", and not any operation? Does
this flag get cleared again after an operation that doesn't need
rounding?
FE_INVALID An invalid operation was attempted FE_OVERFLOW The result of an operation was too big to be represented FE_UNDERFLOW The result of an operation was too small to be represented
In addition to this standard flags, lcc-win32 provides: FE_DENORMAL The result of the last operation was a denormal number FE_STACKFAULT The floating point stack has overflowed.
The denormal flag means that a loss of precision is certain, the number is too small to be represented.
Do you mean "too small to be represented with full precision"?
The stack fault flag means that lcc-win32 generated bad code, since all floating point operations should balance the floating point stack. If you ever test positive for this flag, do not hesitate to send me a bug report!
I don't like this at all. I wouldn't want to write code that checks if
the compiler is broken. If there is any possibility at all that this
happens, could you make this throw a hardware exception, so that it
definitely will get detected?
In general, the floating point flags can be queried by the program to know if the last operation did complete without problems. Here is a small example to show you how this works:
/* This program tests a division by zero */ #include <fenv.h> #include <stdio.h> int main(void) { double a=1,b=0; feclearexcept(FE_DIVBYZERO); a=a/b; if (fetestexcept(FE_DIVBYZERO)) { printf("You have divided by zero!\n"); } return 0; }
First we clear the flag that we are going to use using feclearexcept. Then, we perform our operation and query if the flag is set using fetestexcept.
Since we know that the flags are set but not cleared, the expression could be very well be a much more complicated sequence of operations. The above code would work the same, but we would loose the possibility
**** lose of knowing exactly which operation failed. This is in many cases not
******
I wouldn't say that the operaton failed. Most floating-point operations
will set the FE_INEXACT flag, that doesn't mean they failed.
very important, we could very well be interested that somewhere there was a serious error, without bothering to investigate which operation was that it failed.
Reinitializing the floating point environment ---------------------------------------------
Things can become messy, and you would like to reset everything to a known state. The standard provides the macro FE_DFL_ENV, that represents the address of the default environment, the one you started with. In lcc-win32 this environment is stored in the __default_fe_env global variable, so this macro is just:
#define FE_DFL_ENV (&__default_fe_env)
You can reset everything to its default state with:
fesetenv(FE_DFL_ENV);
The default environment in lcc-win32 has the following characteristics: 1) The rounding mode is set to round to nearest. 2) The precision of the FPU is set to full precision (80 bits) 3) All exceptions are masked, i.e. the result of invalid operations is a NAN, not a trap.
---------------------------------------------------------------------------
Christian Bau a écrit : In article <43***********************@news.wanadoo.fr>, jacob navia <ja***@jacob.remcomp.fr> wrote:
Hi people
I continue to work in the tutorial for lcc-win32, and started to try to explain the floating point flags.
Here is the relevant part of the tutorial. Since it is a difficult part, I would like your expert advise before I publish any serious nonsense.
Any comments are welcome, style, organization, hard errors, etc.
Thanks in advance
jacob -------------------------------------------------------------------
Using the floating point environment ------------------------------------
The C standard specifies a type fenv_t that ³refers collectively to any floating-point status flags and control modes supported by the implementation.²
This environment has two special parts, the ³floating point status flags² that are set by the operations the program performs, and the ³control flags² that changes how the hardware does the operations, for instance the rounding mode, etc.
The status flags ---------------- The standard requires at least the following flags: FE_DIVBYZERO A division by zero has occurred FE_INEXACT The last operation had to be rounded
Are you sure it is "the last operation", and not any operation? Does this flag get cleared again after an operation that doesn't need rounding?
The x87 instruction manual specifies that by most arithmetic
operations, i.e. FADD FSUB, etc this flag is set/unset if the
result needed rounding. The internal flags (C0 C1 C3) specify
the direction of the rounding that was performed: up or down.FE_INVALID An invalid operation was attempted FE_OVERFLOW The result of an operation was too big to be represented FE_UNDERFLOW The result of an operation was too small to be represented
In addition to this standard flags, lcc-win32 provides: FE_DENORMAL The result of the last operation was a denormal number FE_STACKFAULT The floating point stack has overflowed.
The denormal flag means that a loss of precision is certain, the number is too small to be represented.
Do you mean "too small to be represented with full precision"?
Yes, you are right. Thanks. The stack fault flag means that lcc-win32 generated bad code, since all floating point operations should balance the floating point stack. If you ever test positive for this flag, do not hesitate to send me a bug report!
I don't like this at all. I wouldn't want to write code that checks if the compiler is broken. If there is any possibility at all that this happens, could you make this throw a hardware exception, so that it definitely will get detected?
Yes, it would just mean unmasking the exception flag, what would
provoke a trap if a FP stack overflow happens. In general, the floating point flags can be queried by the program to know if the last operation did complete without problems. Here is a small example to show you how this works:
/* This program tests a division by zero */ #include <fenv.h> #include <stdio.h> int main(void) { double a=1,b=0; feclearexcept(FE_DIVBYZERO); a=a/b; if (fetestexcept(FE_DIVBYZERO)) { printf("You have divided by zero!\n"); } return 0; }
First we clear the flag that we are going to use using feclearexcept. Then, we perform our operation and query if the flag is set using fetestexcept.
Since we know that the flags are set but not cleared, the expression could be very well be a much more complicated sequence of operations. The above code would work the same, but we would loose the possibility
**** lose
of knowing exactly which operation failed. This is in many cases not
******
I wouldn't say that the operaton failed. Most floating-point operations will set the FE_INEXACT flag, that doesn't mean they failed.
True, will correct that.
Thanks for your input.
jacob
jacob navia wrote: The status flags ---------------- The standard requires at least the following flags: FE_DIVBYZERO A division by zero has occurred FE_INEXACT The last operation had to be rounded
It would be much more straight forward to say that the result produced
was not the exact mathematical result of the operation. That avoids the
awkwardness of having to define "had to be rounded".
FE_INVALID An invalid operation was attempted FE_OVERFLOW The result of an operation was too big to be represented FE_UNDERFLOW The result of an operation was too small to be
represented
Nit: The magnitude of the result was too large/small to be represented.
In addition to this standard flags, lcc-win32 provides: FE_DENORMAL The result of the last operation was a denormal number FE_STACKFAULT The floating point stack has overflowed.
The denormal flag means that a loss of precision is certain, the number is too small to be represented.
The statement "loss of precision is certain" is accurate, but
misleading. It doesn't imply an erroneous value or loss of accuracy.
A denormalized number is too small to be represented with full
precision, but not too small to be represented at all.
In general, the floating point flags can be queried by the program to know if the last operation did complete without problems. Here is a
suggest: completed ^^^^^^^^^^^^ small example to show you how this works:
/* This program tests a division by zero */ #include <fenv.h> #include <stdio.h> int main(void) { double a=1,b=0; feclearexcept(FE_DIVBYZERO); a=a/b; if (fetestexcept(FE_DIVBYZERO)) { printf("You have divided by zero!\n"); } return 0; }
First we clear the flag that we are going to use using feclearexcept.
First we clear the flag FE_DIVBYZERO using feclearexcept.
Then, we perform our operation and query if the flag is set using fetestexcept.
We next perform the divide, then test the flag using fetestexcept. Since we know that the flags are set but not cleared, the expression
xxxxxxxxxxxx could be very well be a much more complicated sequence of operations. The above code would work the same, but we would loose the possibility of knowing exactly which operation failed. This is in many cases not very important, we could very well be interested that somewhere there
xxxx . We might only need to know was a serious error, without bothering to investigate which operation
knowing precisely where. was that it failed.
--
Thad
Thad Smith a écrit : jacob navia wrote:
The status flags ---------------- The standard requires at least the following flags: FE_DIVBYZERO A division by zero has occurred FE_INEXACT The last operation had to be rounded
It would be much more straight forward to say that the result produced was not the exact mathematical result of the operation. That avoids the awkwardness of having to define "had to be rounded".
OK, it is a better formulation. Will change that. FE_INVALID An invalid operation was attempted FE_OVERFLOW The result of an operation was too big to be represented > FE_UNDERFLOW The result of an operation was too small to be represented
Nit: The magnitude of the result was too large/small to be represented.
Mmmm, if I use magnitude I would have to explain what does that mean
in this context. I do explain in a previous chapter the floating
point format, so I could go back to that and explain overflow
explicitely with normal --> denormal --> overflow In addition to this standard flags, lcc-win32 provides: FE_DENORMAL The result of the last operation was a denormal number FE_STACKFAULT The floating point stack has overflowed.
The denormal flag means that a loss of precision is certain, the number is too small to be represented.
The statement "loss of precision is certain" is accurate, but misleading. It doesn't imply an erroneous value or loss of accuracy.
A denormalized number is too small to be represented with full precision, but not too small to be represented at all.
In general, the floating point flags can be queried by the program to know if the last operation did complete without problems. Here is a
suggest: completed ^^^^^^^^^^^^
Yes, typo. Thanks small example to show you how this works:
/* This program tests a division by zero */ #include <fenv.h> #include <stdio.h> int main(void) { double a=1,b=0; feclearexcept(FE_DIVBYZERO); a=a/b; if (fetestexcept(FE_DIVBYZERO)) { printf("You have divided by zero!\n"); } return 0; }
First we clear the flag that we are going to use using feclearexcept.
First we clear the flag FE_DIVBYZERO using feclearexcept.
Then, we perform our operation and query if the flag is set using fetestexcept.
We next perform the divide, then test the flag using fetestexcept.
Since we know that the flags are set but not cleared, the expression
xxxxxxxxxxxx
could be very well be a much more complicated sequence of operations. The above code would work the same, but we would loose the possibility of knowing exactly which operation failed. This is in many cases not very important, we could very well be interested that somewhere there
xxxx . We might only need to know > was a serious error, without bothering to investigate which operation knowing precisely where.
was that it failed.
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Dave |
last post by:
Hi folks,
I am trying to develop a routine that will handle sphere-sphere and
sphere-triangle collisions and interactions. My aim is to develop a
quake style collision engine where a player can...
|
by: JS |
last post by:
We have the same floating point intensive C++ program that runs on
Windows on Intel chip and on Sun Solaris on SPARC chips. The program
reads the exactly the same input files on the two platforms....
|
by: Anton Noll |
last post by:
We are using Visual Studio 2003.NET (C++) for the development
of our software in the fields digital signal processing and
numerical acoustics.
One of our programs was working correctly if we are...
|
by: cody |
last post by:
no this is no trollposting and please don't get it wrong but iam very
curious why people still use C instead of other languages especially C++.
i heard people say C++ is slower than C but i can't...
|
by: Vinoth |
last post by:
I'm working in an ARM (ARM9) system which does not have Floating point
co-processor or Floating point libraries. But it does support long long int
(64 bits).
Can you provide some link that would...
|
by: ma740988 |
last post by:
template <class T> inline bool isEqual( const T& a, const T& b,
const T epsilon = std::numeric_limits<T>::epsilon() )
{
const T diff = a - b;
return ( diff <= epsilon ) && ( diff >= -epsilon );...
|
by: Peter Sprenger |
last post by:
Hello,
I want to efficient convert floating point numbers (IEEE754) into a
string. I have no library routines that do the job (like sprintf etc.),
because I work in an embedded environment.
...
|
by: rembremading |
last post by:
Hi all!
The following piece of code has (for me) completely unexpected behaviour.
(I compile it with gcc-Version 4.0.3)
Something goes wrong with the integer to float conversion.
Maybe somebody...
|
by: ssubbarayan |
last post by:
Hi all,
I am trying a program to convert floating point values to a byte array
and printing the same to the screen.The idea behind this is we already
have an existing function which can do byte...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
| |