bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: clang-10 warning in hash.c


From: Bruno Haible
Subject: Re: clang-10 warning in hash.c
Date: Tue, 28 Jan 2020 03:08:29 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-171-generic; KDE/5.18.0; x86_64; ; )

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]