I wrote: > And I dislike it because the transformation is correct only if > (float) SIZE_MAX >= SIZE_MAX. In the other case, > (float) SIZE_MAX < SIZE_MAX, the transformation is incorrect > [think of the particular value new_candidate = (float) SIZE_MAX].
Ouch, I was assuming that the comparison should be done according to exact mathematical value (infinite precision), like it is in Common Lisp. It's not the case in C! The integer gets rounded to the floating-point type first, leading to surprising results: =============================================================== #include <stdio.h> volatile unsigned long long pi; volatile long long ni; volatile float pf = 65536.0f * 65536.0f * 65536.0f * 65536.0f; volatile float nf = - 32768.0f * 65536.0f; int compare1 (void) { return pi <= pf; } int compare1ld (void) { return (long double) pi <= (long double) pf; } int compare2 (void) { return ni <= nf; } int compare2d (void) { return (double) ni <= (double) nf; } int main () { pi = 0xFFFFFFFFFFFFFFFFUL; printf ("%d %d\n", compare1 (), compare1ld ()); ni = -0x7FFFFFFF; printf ("%d %d\n", compare2 (), compare2d ()); } =============================================================== Produces: 1 1 1 0 And with '<' instead of '<=': =============================================================== #include <stdio.h> volatile unsigned long long pi; volatile long long ni; volatile float pf = 65536.0f * 65536.0f * 65536.0f * 65536.0f; volatile float nf = - 32768.0f * 65536.0f; int compare1 (void) { return pi < pf; } int compare1ld (void) { return (long double) pi < (long double) pf; } int compare2 (void) { return ni < nf; } int compare2d (void) { return (double) ni < (double) nf; } int main () { pi = 0xFFFFFFFFFFFFFFFFUL; printf ("%d %d\n", compare1 (), compare1ld ()); ni = -0x7FFFFFFF; printf ("%d %d\n", compare2 (), compare2d ()); } =============================================================== Produces: 0 1 0 0 Bruno