J
jacob navia
Following the discussion about the machine epsilon, I have modified the
text as follows. I thank all people that contributed. It was
interesting, and I surely learned stuff I did not consider before.
--------------------------------------------------------------
The machine epsilon
-------------------
The standard defines for each floating point representation (float,
double, long double) the difference between 1 and the least value
greater than 1 that is representable in the given floating point type.
In IEEE754 representation this number has an exponent value of the bias,
and a fraction of 1. In hexadecimal notation this would be
0x1p-52
Another way to define this quantity in terms of the mathematical
functions of the C library is:
DBL_EPSILON = nextafter(1.0,2.0) - 1.0;
For the different representations we have in the standard header <float.h>:
#define FLT_EPSILON 1.19209290e-07F // float
#define DBL_EPSILON 2.2204460492503131e-16 // double
#define LDBL_EPSILON 1.084202172485504434007452e-19L //long double
// qfloat epsilon truncated so that it fits in this page...
#define QFLT_EPSILON 1.09003771904865842969737513593110651 ... E-106
These definitions (except the qfloat part) are part of the C99 ANSI
standard. For the standard types (float, double and long double) they
should always exist in other compilers.
Here is a program that will find out the machine epsilon for a given
floating point representation.
#include <stdio.h>
int main(void)
{
double float_radix=2.0;
double inverse_radix = 1.0/float_radix;
double machine_precision = 1.0;
double temp = 1.0 + machine_precision;
while (temp != 1.0) {
machine_precision *= inverse_radix;
temp = 1.0 + machine_precision ;
printf("%.17g\n",machine_precision);
}
return 0;
}
Exercises:
1: Explain why in the above program, the value of DBL_EPSILON is not the
last number but the number before.
2: An alternative version of the above program is:
#include <stdio.h>
int main(void)
{
volatile double oneplus = 2, epsilon = 1;
while (1 + epsilon/2 > 1) {
epsilon /= 2;
oneplus = 1 + epsilon;
}
epsilon = oneplus - 1;
printf("DBL_EPSILON is %g\n", epsilon);
return 0;
}
Explain why this program prints
DBL_EPSILON is 0
in lcc-win32.
text as follows. I thank all people that contributed. It was
interesting, and I surely learned stuff I did not consider before.
--------------------------------------------------------------
The machine epsilon
-------------------
The standard defines for each floating point representation (float,
double, long double) the difference between 1 and the least value
greater than 1 that is representable in the given floating point type.
In IEEE754 representation this number has an exponent value of the bias,
and a fraction of 1. In hexadecimal notation this would be
0x1p-52
Another way to define this quantity in terms of the mathematical
functions of the C library is:
DBL_EPSILON = nextafter(1.0,2.0) - 1.0;
For the different representations we have in the standard header <float.h>:
#define FLT_EPSILON 1.19209290e-07F // float
#define DBL_EPSILON 2.2204460492503131e-16 // double
#define LDBL_EPSILON 1.084202172485504434007452e-19L //long double
// qfloat epsilon truncated so that it fits in this page...
#define QFLT_EPSILON 1.09003771904865842969737513593110651 ... E-106
These definitions (except the qfloat part) are part of the C99 ANSI
standard. For the standard types (float, double and long double) they
should always exist in other compilers.
Here is a program that will find out the machine epsilon for a given
floating point representation.
#include <stdio.h>
int main(void)
{
double float_radix=2.0;
double inverse_radix = 1.0/float_radix;
double machine_precision = 1.0;
double temp = 1.0 + machine_precision;
while (temp != 1.0) {
machine_precision *= inverse_radix;
temp = 1.0 + machine_precision ;
printf("%.17g\n",machine_precision);
}
return 0;
}
Exercises:
1: Explain why in the above program, the value of DBL_EPSILON is not the
last number but the number before.
2: An alternative version of the above program is:
#include <stdio.h>
int main(void)
{
volatile double oneplus = 2, epsilon = 1;
while (1 + epsilon/2 > 1) {
epsilon /= 2;
oneplus = 1 + epsilon;
}
epsilon = oneplus - 1;
printf("DBL_EPSILON is %g\n", epsilon);
return 0;
}
Explain why this program prints
DBL_EPSILON is 0
in lcc-win32.