Back to index

glibc  2.9
printf_fphex.c
Go to the documentation of this file.
00001 /* Print floating point number in hexadecimal notation according to ISO C99.
00002    Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006,2007
00003        Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
00006 
00007    The GNU C Library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public
00009    License as published by the Free Software Foundation; either
00010    version 2.1 of the License, or (at your option) any later version.
00011 
00012    The GNU C Library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License along with the GNU C Library; if not, write to the Free
00019    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00020    02111-1307 USA.  */
00021 
00022 #define PRINT_FPHEX_LONG_DOUBLE \
00023 do {                                                                 \
00024       /* We have 105 bits of mantissa plus one implicit digit.  Since       \
00025         106 bits are representable without rest using hexadecimal           \
00026         digits we use only the implicit digits for the number before        \
00027         the decimal point.  */                                              \
00028       unsigned long long int num0, num1;                             \
00029       unsigned long long hi, lo;                                     \
00030       int ediff;                                                     \
00031       union ibm_extended_long_double eldbl;                                 \
00032       eldbl.d = fpnum.ldbl.d;                                               \
00033                                                                      \
00034       assert (sizeof (long double) == 16);                                  \
00035                                                                      \
00036       lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3;    \
00037       hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1;    \
00038       lo <<= 7; /* pre-shift lo to match ieee854.  */                       \
00039       /* If the lower double is not a denomal or zero then set the hidden     \
00040         53rd bit.  */                                                       \
00041       if (eldbl.ieee.exponent2 != 0)                                        \
00042        lo |= (1ULL << (52 + 7));                                     \
00043       else                                                           \
00044        lo <<= 1;                                                     \
00045       /* The lower double is normalized separately from the upper.  We             \
00046         may need to adjust the lower manitissa to reflect this.  */         \
00047       ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2;                   \
00048       if (ediff > 53 + 63)                                           \
00049        lo = 0;                                                              \
00050       else if (ediff > 53)                                           \
00051        lo = lo >> (ediff - 53);                                      \
00052       else if (eldbl.ieee.exponent2 == 0 && ediff < 53)                     \
00053        lo = lo << (53 - ediff);                                      \
00054       if (eldbl.ieee.negative != eldbl.ieee.negative2                       \
00055          && (eldbl.ieee.exponent2 != 0 || lo != 0L))                        \
00056        {                                                             \
00057          lo = (1ULL << 60) - lo;                                     \
00058          if (hi == 0L)                                                      \
00059            {                                                         \
00060              /* we have a borrow from the hidden bit, so shift left 1.  */   \
00061              hi = 0xffffffffffffeLL | (lo >> 59);                           \
00062              lo = 0xfffffffffffffffLL & (lo << 1);                          \
00063              eldbl.ieee.exponent--;                                         \
00064            }                                                         \
00065          else                                                        \
00066            hi--;                                                     \
00067         }                                                            \
00068       num1 = (hi << 60) | lo;                                               \
00069       num0 = hi >> 4;                                                       \
00070                                                                      \
00071       zero_mantissa = (num0|num1) == 0;                                     \
00072                                                                      \
00073       if (sizeof (unsigned long int) > 6)                            \
00074        {                                                             \
00075          numstr = _itoa_word (num1, numbuf + sizeof numbuf, 16,             \
00076                             info->spec == 'A');                      \
00077          wnumstr = _itowa_word (num1,                                       \
00078                              wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),\
00079                              16, info->spec == 'A');                 \
00080        }                                                             \
00081       else                                                           \
00082        {                                                             \
00083          numstr = _itoa (num1, numbuf + sizeof numbuf, 16,                  \
00084                        info->spec == 'A');                                  \
00085          wnumstr = _itowa (num1,                                     \
00086                          wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),    \
00087                          16, info->spec == 'A');                     \
00088        }                                                             \
00089                                                                      \
00090       while (numstr > numbuf + (sizeof numbuf - 64 / 4))                    \
00091        {                                                             \
00092          *--numstr = '0';                                            \
00093          *--wnumstr = L'0';                                          \
00094        }                                                             \
00095                                                                      \
00096       if (sizeof (unsigned long int) > 6)                            \
00097        {                                                             \
00098          numstr = _itoa_word (num0, numstr, 16, info->spec == 'A');         \
00099          wnumstr = _itowa_word (num0, wnumstr, 16, info->spec == 'A');             \
00100        }                                                             \
00101       else                                                           \
00102        {                                                             \
00103          numstr = _itoa (num0, numstr, 16, info->spec == 'A');              \
00104          wnumstr = _itowa (num0, wnumstr, 16, info->spec == 'A');           \
00105        }                                                             \
00106                                                                      \
00107       /* Fill with zeroes.  */                                              \
00108       while (numstr > numbuf + (sizeof numbuf - 112 / 4))                   \
00109        {                                                             \
00110          *--numstr = '0';                                            \
00111          *--wnumstr = L'0';                                          \
00112        }                                                             \
00113                                                                      \
00114       leading = eldbl.ieee.exponent == 0 ? '0' : '1';                       \
00115                                                                      \
00116       exponent = eldbl.ieee.exponent;                                       \
00117                                                                      \
00118       if (exponent == 0)                                             \
00119        {                                                             \
00120          if (zero_mantissa)                                          \
00121            expnegative = 0;                                          \
00122          else                                                        \
00123            {                                                         \
00124              /* This is a denormalized number.  */                          \
00125              expnegative = 1;                                               \
00126              exponent = IBM_EXTENDED_LONG_DOUBLE_BIAS - 1;                  \
00127            }                                                         \
00128        }                                                             \
00129       else if (exponent >= IBM_EXTENDED_LONG_DOUBLE_BIAS)                   \
00130        {                                                             \
00131          expnegative = 0;                                            \
00132          exponent -= IBM_EXTENDED_LONG_DOUBLE_BIAS;                         \
00133        }                                                             \
00134       else                                                           \
00135        {                                                             \
00136          expnegative = 1;                                            \
00137          exponent = -(exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS);            \
00138        }                                                             \
00139 } while (0)
00140 
00141 #include <stdio-common/printf_fphex.c>