This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

bz1311954 - multilib variations in LC_COLLATE files, with fixes


https://bugzilla.redhat.com/show_bug.cgi?id=1311954

Fedora BZ 1311954 saw that the locale archives were not the same
across all builds; partly that was due to big vs little endian, but
there were differences between 32 and 64-bit on both s390 and x86.

In locale/programs/ld-collate.c we see this:

  /* Add 40% and find the next prime number.  */
  elem_size = next_prime (elem_size * 1.4);

After debugging this for a week, it turned out that when elem_size is
120, "elem_size * 1.4" is 168 - but not exactly 168.  Since 1.4 isn't
exactly representable in IEEE, the result was either 168.00000001 or
167.9999999 - and it turns out that 167 *is prime* so the next_prime()
call returned completely different results depending on the FPU and
rounding.

The solution is to avoid floating point math.

Since elem_size is limited by locale limits, overflow isn't much of a
problem.  There are a couple of simple changes, but which to choose?

/* Same value as before, but "/10" isn't exact */
  elem_size = next_prime (elem_size * 14/10);

/* Slightly different value (37.5%) but now it's exact */
  elem_size = next_prime (elem_size * 11/8);

/* Same as above, but without extra chance of overflow */
  elem_size = next_prime (elem_size + (elem_size>>2) + (elem_size>>3));


Note this math also happens in ./iconv/iconvconfig.c:
  hash_size = next_prime (nnames * 1.4); 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]