Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

DGDouble.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file DGDouble.d
00004         
00005         Copyright (c) 2004 Kris Bell
00006         
00007         This software is provided 'as-is', without any express or implied
00008         warranty. In no event will the authors be held liable for damages
00009         of any kind arising from the use of this software.
00010         
00011         Permission is hereby granted to anyone to use this software for any 
00012         purpose, including commercial applications, and to alter it and/or 
00013         redistribute it freely, subject to the following restrictions:
00014         
00015         1. The origin of this software must not be misrepresented; you must 
00016            not claim that you wrote the original software. If you use this 
00017            software in a product, an acknowledgment within documentation of 
00018            said product would be appreciated but is not required.
00019 
00020         2. Altered source versions must be plainly marked as such, and must 
00021            not be misrepresented as being the original software.
00022 
00023         3. This notice may not be removed or altered from any distribution
00024            of the source.
00025 
00026         4. Derivative works are permitted, but they must carry this notice
00027            in full and credit the original source.
00028 
00029 
00030                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00031 
00032         
00033         @version        Initial version, Feb 2005
00034         @author         Kris
00035 
00036 
00037 *******************************************************************************/
00038 
00039 module mango.format.DGDouble;
00040 
00041 private import mango.format.Number;
00042 
00043 /*******************************************************************************
00044         
00045         Callback for dtoa allocation function
00046 
00047 *******************************************************************************/
00048 
00049 extern (C)
00050 {
00051         void* __dToaMalloc (uint size)
00052         {
00053                 throw new Exception ("unexpected memory request from DGDouble");
00054                 return new byte[2048];
00055         }
00056 
00057         char*  dtoa (double d, int mode, int ndigits, int* decpt, int* sign, char** rve);
00058         double atod (char* s00, int len, char** se);
00059 }
00060 
00061 
00062 /******************************************************************************
00063 
00064         David Gay's extended conversions between string and floating-point
00065         numeric representations. Use these where you need extended accuracy
00066         when converting. 
00067 
00068         Note that this class requires the attendent dtoa.c file to be 
00069         compiled into the Mango library.
00070 
00071 ******************************************************************************/
00072 
00073 class DGDouble : Number
00074 {
00075         /**********************************************************************
00076 
00077                 Convert a formatted string of digits to a floating-
00078                 point number. 
00079 
00080         **********************************************************************/
00081 
00082         final static double parse (tChar[] src, uint* ate=null)
00083         {
00084                 char* end;
00085 
00086                 double x = atod (src.ptr, src.length, &end);
00087                 if (ate)
00088                     *ate = end - src.ptr;
00089                 return x;
00090         }
00091 
00092 
00093         /**********************************************************************
00094 
00095                 Convert a floating-point number to a string. Parameter 'mode'
00096                 should be specified thusly:
00097 
00098                 0 ==> shortest string that yields d when read in
00099                         and rounded to nearest.
00100 
00101                 1 ==> like 0, but with Steele & White stopping rule;
00102                         e.g. with IEEE P754 arithmetic , mode 0 gives
00103                         1e23 whereas mode 1 gives 9.999999999999999e22.
00104 
00105                 2 ==> max(1,ndigits) significant digits.  This gives a
00106                         return value similar to that of ecvt, except
00107                         that trailing zeros are suppressed.
00108 
00109                 3 ==> through ndigits past the decimal point.  This
00110                         gives a return value similar to that from fcvt,
00111                         except that trailing zeros are suppressed, and
00112                         ndigits can be negative.
00113 
00114                 4,5 ==> similar to 2 and 3, respectively, but (in
00115                         round-nearest mode) with the tests of mode 0 to
00116                         possibly return a shorter string that rounds to d.
00117                         With IEEE arithmetic and compilation with
00118                         -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
00119                         as modes 2 and 3 when FLT_ROUNDS != 1.
00120 
00121                 6-9 ==> Debugging modes similar to mode - 4:  don't try
00122                         fast floating-point estimate (if applicable).
00123 
00124         **********************************************************************/
00125 
00126         static final tChar[] format (tChar[] dst, double x, uint decimals = 6, bool scientific = false, uint mode=3)
00127         in {
00128            assert (dst.length >= 32);
00129            }
00130         body
00131         {
00132                 char*   end,
00133                         str;
00134                 int     sign,
00135                         decpt;
00136                   
00137                 str = dtoa (x, mode, decimals, &decpt, &sign, &end);
00138                 
00139                 char *p = dst;
00140                 int len = end - str;
00141 
00142                 if (sign)
00143                     *p++ = '-';
00144 
00145                 if (decpt == 9999)
00146                     p[0..len] = str[0..len];
00147                 else
00148                    {
00149                    int exp = decpt - 1;
00150                    sign = 0;
00151                    if (exp < 0)
00152                       {
00153                       exp = -exp;
00154                       sign = 1;
00155                       }
00156 
00157                    // force scientific format if too long ...
00158                    if ((exp + len + 2) > dst.length)
00159                         scientific = true;
00160 
00161                    if (scientific)
00162                       {
00163                       *p++ = *str++;
00164                       *p++ = '.';
00165                       while (str < end)
00166                              *p++ = *str++;
00167                       *p++ = 'e';
00168                       *p++ = (sign) ? '-' : '+';
00169    
00170                       if (exp >= 100)
00171                          {
00172                          *p++ = exp / 100 + '0';
00173                          exp %= 100;
00174                          }
00175                       *p++ = exp / 10 + '0';
00176                       *p++ = exp % 10 + '0';
00177                       }
00178                    else
00179                       {
00180                       if (decpt <= 0)
00181                           *p++ = '0';
00182                       else
00183                          {
00184                          while (decpt > 0)
00185                                {
00186                                *p++ = (str < end) ? *str++ : '0';
00187                                --decpt;
00188                                }
00189                          }
00190                       if (str < end)
00191                          {
00192                          *p++ = '.';
00193                          while (decpt < 0)
00194                                {
00195                                *p++ = '0';
00196                                ++decpt;
00197                                }
00198                          while (str < end)
00199                                 *p++ = *str++;
00200                          }
00201                       } 
00202                    }
00203                          
00204                 return dst[0..(p - dst.ptr)];
00205         }
00206 }
00207 
00208 

Generated on Sat Apr 9 20:11:25 2005 for Mango by doxygen 1.3.6