Greetings all,
I am converting some floating point numbers to (signed or unsigned)
integers I am not getting the expected results. It is perhaps the result
of the C libraries/compiler that I am using. I have reproduced the same
results on Intel and AMD processors.
As I understand, floating point conversion should be provided as a
fundamental operation in an IEEE compliant FP implementation.
Furthermore, in conversions the rounding schemes below should apply in
the same way that they are applied to the result of one of the
operations (+,-,*,/).
The code below has been compiled with gcc on linux platforms, using the
GNU C libraries.
===================================================================
Code
----
/*
* A program to print the conversions between fp and integer numbers.
*/
#include <fenv.h>
#include <stdio.h>
#include <stdlib.h>
main (void) {
float float_a=1.6,float_b=1.4,float_c=1.2;
int rnd,direct_conv,add_conv;
char *rnd_str = malloc(8);
for (rnd=0;rnd<4;rnd++) {
/* set the rounding mode */
if (rnd==0) {
fesetround(FE_TONEAREST);
rnd_str = "TO NEAR";
} else if (rnd==1) {
fesetround(FE_TOWARDZERO);
rnd_str = "TO ZERO";
} else if (rnd==2) {
fesetround(FE_UPWARD);
rnd_str = "TO +INF";
} else if (rnd==3) {
fesetround(FE_DOWNWARD);
rnd_str = "TO -INF";
}
/* convert floats to integers */
direct_conv = (int)float_a;
add_conv = (int)(float_b + float_c);
printf("\n| Round mode (%s)\n| ------------------------\n",rnd_str);
printf("| float -> int\n");
printf("| direct: %1.1f -> %i\n",float_a,direct_conv);
printf("| add : %1.1f + %1.1f -> %i\n\n",
float_b,float_c,add_conv);
}
}
===================================================================
Output*
------
| Round mode (TO NEAR)
| ------------------------
| float -> int
| direct: 1.6 -> 1 [2]#
| add : 1.4 + 1.2 -> 2 {3,2}
| Round mode (TO ZERO)
| ------------------------
| float -> int
| direct: 1.6 -> 1 [1]
| add : 1.4 + 1.2 -> 2 {2,2}
| Round mode (TO +INF)
| ------------------------
| float -> int
| direct: 1.6 -> 1 [2]#
| add : 1.4 + 1.2 -> 2 {3,4}
| Round mode (TO -INF)
| ------------------------
| float -> int
| direct: 1.6 -> 1 [1]
| add : 1.4 + 1.2 -> 2 {2,2}
===================================================================
* I have added my expected results in brackets to the right of the
calculated result. Differing results are marked with a pound sign (#).
[direct-conversion]
{add-then-convert,convert-then-add}
Now, I am primarily concerned only with the direct conversion case, I
have included the add-and-convert-result case just as an additional
anomaly.
Looking at the results above, it would appear that the rounding mode is
being ignored in all cases, and the default "rounding" action is merely
to truncate results.
1.6 (base10) = 1.1001100110011... (base2)
So, are the (#) results different to that expected because of my
understanding IEEE 754, something to do with the GNU C library, the
compiler, or the processor?
Thanks,
- Dan


|