decNumber package errata IBM

The current generally available release of the decNumber package is 3.56 (2007.10.12). Since then, two minor bugs have been reported. This page details the problems and the fixes. Only the decDoubleSubtract, decQuadSubtract, decDoubleQuantize, and decQuadQuantize functions are affected.

Please send any comments, questions, and corrections on these directly to me (Mike Cowlishaw, mfc@uk.ibm.com).


  1. Expression in macro is subject to reordering.

    The ISCOEFFZERO macro (in decNumberLocal.h) incorrectly used UBTOUI twice in the same expression. This could cause a wrong result when optimized by a compiler that aggressively takes advantage of C99 strict aliasing rules (see Mike Acton’s page for an excellent explanation of this).

    The fix is to either turn off strict aliasing optimizations, or to replace the macro (actually the three implementations of the macro) by the following:

     /* Macro to test whether a full-length (length DECPMAX) BCD8      */
     /* coefficient, starting at uByte u, is all zeros                 */
     /* Test just the LSWord first, then the remainder as a sequence   */
     /* of tests in order to avoid same-level use of UBTOUI            */
     #if DECPMAX==7
       #define ISCOEFFZERO(u) (                                      \
            UBTOUI((u)+DECPMAX-4)==0                                 \
         && UBTOUS((u)+DECPMAX-6)==0                                 \
         && *(u)==0)
     #elif DECPMAX==16
       #define ISCOEFFZERO(u) (                                      \
            UBTOUI((u)+DECPMAX-4)==0                                 \
         && UBTOUI((u)+DECPMAX-8)==0                                 \
         && UBTOUI((u)+DECPMAX-12)==0                                \
         && UBTOUI(u)==0)
     #elif DECPMAX==34
       #define ISCOEFFZERO(u) (                                      \
            UBTOUI((u)+DECPMAX-4)==0                                 \
         && UBTOUI((u)+DECPMAX-8)==0                                 \
         && UBTOUI((u)+DECPMAX-12)==0                                \
         && UBTOUI((u)+DECPMAX-16)==0                                \
         && UBTOUI((u)+DECPMAX-20)==0                                \
         && UBTOUI((u)+DECPMAX-24)==0                                \
         && UBTOUI((u)+DECPMAX-28)==0                                \
         && UBTOUI((u)+DECPMAX-32)==0                                \
         && UBTOUS(u)==0)
     #endif
    
    Many thanks to John Matzka for finding this one.

  2. Incorrectly sized buffer.

    A buffer in decFloatQuantize (in decBasic.c) is two bytes too short when the coefficient of the first operand has to be extended with 33 zeros (this only affects decQuadQuantize).

    The fix is to replace the line

     uByte buf[4+DECPMAX*3];     // + space for zeros to left or right
    
    with
     uByte buf[4+DECPMAX*3+2*QUAD]; // + space for zeros to left or right
    
    Many thanks to Klaus Kretzschmar for finding this one.

 
Copyright © IBM Corporation, 2008. All rights reserved.
[ IBM home page | Search | Contact IBM | Help | Terms of use | Privacy ]