This program tests the setround/getround
primitives.
The program divides 1 by 3 with two different settings
of fesetround: upward and downard. Obviously
the result should be different in the last bit.
-----------------------------------------cut here
#include <stdio.h>
#include <math.h>
#include <fenv.h>
#include <assert.h>
#include <stdint.h>
#pragma STDC FP_CONTRACT OFF
#pragma STDC FENV_ACCESS ON
double foo(int round_dir,double d)
{
double result;
int save_round;
int setround_ok;
save_round = fegetround();
setround_ok = fesetround(round_dir);
assert(setround_ok == 0);
result = 1.0/d;
fesetround(save_round);
return result;
}
static void print_double(double d)
{
uint32_t *pint;
pint = (uint32_t *)&d;
// For little endian machines (x86)
// use 1 then zero
// For Big endian machines (power pc)
// use 0 then 1
printf("0x%x%x\n",pint[1],pint[0]);
}
int main(void)
{
double d1 = foo(FE_UPWARD,3.0);
double d2 = foo(FE_DOWNWARD,3.0);
print_double(d1);
print_double(d2);
}
------------------------------------------cut here
Output:
0x3fd5555555555556
0x3fd5555555555555
Passes under windows lcc-win, gcc, and AIX xlc
Note that in principle you should be able to put
the standard pragmas within a compound statement
and they should be local to that compound statement.
This is quite difficult to implement in real
world compilers. Neither gcc nor xlc (AIX)
have completely rewritten their code generation
phase to satisfy this crazy requirement.
lcc-win ignores those pragmas for the moment.
Besides that detail, C99 compilers support
the setting/unsetting of the floating point environment,
a bonus for complicated calculations!
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32