cvs commit: src/lib/msun/src k_tanf.c

Bruce Evans bde at FreeBSD.org
Tue Nov 1 21:37:33 PST 2005


bde         2005-11-02 05:37:32 UTC

  FreeBSD src repository

  Modified files:
    lib/msun/src         k_tanf.c 
  Log:
  Fixed some of the silliness related to rev.1.8.  In 1.8, "double" in
  a declaration was not translated to "float" although bit fiddling on
  double variables was translated.  This resulted in garbage being put
  into the low word of one of the doubles instead of non-garbage being
  put into the only word of the intended float.  This had no effect on
  any result because:
  - with doubles, the algorithm for calculating -1/(x+y) is unnecessarily
    complicated.  Just returning -1/((double)x+y) would work, and the
    misdeclaration gave something like that except for messing up some
    low bits with the bit fiddling.
  - doubles have plenty of bits to spare so messing up some of the low
    bits is unlikely to matter.
  - due to other bugs, the buggy code is reached for a whole 4 args out
    of all 2**32 float args.  The bug fixed by 1.8 only affects a small
    percentage of cases and a small percentage of 4 is 0.  The 4 args
    happen to cause no problems without 1.8, so they are even less likely
    to be affected by the bug in 1.8 than average args; in fact, neither
    1.8 nor this commit makes any difference to the result for these 4
    args (and thus for all args).
  
  Corrections to the log message in 1.8: the bug only applies to tan()
  and not tanf(), not because the float type can't represent numbers
  large enough to trigger the problem (e.g., the example in the fdlibm-5.3
  readme which is > 1.0e269), but because:
  - the float type can't represent small enough numbers.  For there to be
    a possible problem, the original arg for tanf() must lie very near an
    odd multiple of pi/2.  Doubles can get nearer in absolute units.  In
    ulps there should be little difference, but ...
  - ... the cutoff for "small" numbers is bogus in k_tanf.c.  It is still
    the double value (2**-28).  Since this is 32 times smaller than
    FLT_EPSILON and large float values are not very uniformly distributed,
    only 6 args other than ones that are initially below the cutoff give
    a reduced arg that passes the cutoff (the 4 problem cases mentioned
    above and 2 non-problem cases).
  
  Fixing the cutoff makes the bug affect tanf() and much easier to detect
  than for tan().  With a cutoff of 2**-12 on amd64 with -O1, 670102
  args pass the cutoff; of these, there are 337604 cases where there
  might be an error of >= 1 ulp and 5826 cases where there is such an
  error; the maximum error is 1.5382 ulps.
  
  The fix in 1.8 works with the reduced cutoff in all cases despite the
  bug in it.  It changes the result in 84492 cases altogether to fix the
  5826 broken cases.  Fixing the fix by translating "double" to "float"
  changes the result in 42 cases relative to 1.8.  In 24 cases the
  (absolute) error is increased and in 18 cases it is reduced, but it
  remains less than 1 ulp in all cases.
  
  Revision  Changes    Path
  1.9       +1 -1      src/lib/msun/src/k_tanf.c


More information about the cvs-all mailing list