/*
 * The contents of this file are subject to the Netscape Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/NPL/

 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.

 * The Original Code is Rhino code, released
 * May 6, 1999.

 * The Initial Developer of the Original Code is Netscape
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1997-1999 Netscape Communications Corporation. All
 * Rights Reserved.

 * Contributor(s): 

 * Alternatively, the contents of this file may be used under the
 * terms of the GNU Public License (the "GPL"), in which case the
 * provisions of the GPL are applicable instead of those above.
 * If you wish to allow use of your version of this file only
 * under the terms of the GPL and not to allow others to use your
 * version of this file under the NPL, indicate your decision by
 * deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL.  If you do not delete
 * the provisions above, a recipient may use your version of this
 * file under either the NPL or the GPL.
 */
#ifdef DTOA

#ifndef _JS_DTOA_H_
#define _JS_DTOA_H_

#include "js-types.h"
#include "js-biginteger.h"
#include "js-stringbuffer.h"

/* Classes */
class JSDToA {
    protected:
        /*
         * "-0.0000...(1073 zeros after decimal point)...0001\0" is the
         * longest string that we could produce, which occurs
         * when printing -5e-324 in binary.
         * We could compute a better estimate of the size of the output
         * string and malloc fewer bytes depending on d and base,
         * but why bother?
        */
        static const int        DTOBASESTR_BUFFER_SIZE = 1078;

        static const int        Frac_mask = 0xfffff;
        static const int        Exp_shift = 20;
        static const int        Exp_msk1 = 0x100000;
        static const int        Bias = 1023;
        static const int        P = 53;

        static const int        Exp_shift1 = 20;
        static const int        Exp_mask  = 0x7ff00000;
        static const int        Bndry_mask  = 0xfffff;
        static const int        Log2P = 1;

        static const int        Sign_bit = 0x80000000;
        static const int        Exp_11  = 0x3ff00000;
        static const int        Ten_pmax = 22;
        static const int        Quick_max = 14;
        static const int        Bletch = 0x10;
        static const int        Frac_mask1 = 0xfffff;
        static const int        Int_max = 14;
        static const int        n_bigtens = 5;

        static const double     tens[23];
        static const double     bigtens[5];
        /* Mapping of JSDToStrMode -> JS_dtoa mode */
        static const int        dtoaModes[5];

    public:
        /* Either fixed or exponential format; round-trip */
        static const int        DTOSTR_STANDARD = 0;
        /* Always exponential format; round-trip */
        static const int        DTOSTR_STANDARD_EXPONENTIAL = 1;
        /* Round to <precision> digits after the decimal point;
           exponential if number is large */
        static const int        DTOSTR_FIXED = 2;
        /* Always exponential format; <precision> significant digits */
        static const int        DTOSTR_EXPONENTIAL = 3;
        /* Either fixed or exponential format; <precision> significant digits */
        static const int        DTOSTR_PRECISION = 4;

    protected:
        static  int64_t doubleToLongBits(double d);
        static  double  longBitsToDouble(int64_t bits);
        static  jsChar_t
                        BASEDIGIT(int digit);
        static  int     lo0bits(int32_t y);
        static  int     hi0bits(int32_t x);
        static  void    stuffBits(JSBigInteger::Digit *bits, int offset,
                                int val);
        static  JSBigInteger
                        d2b(JSContext *cx, double d, int *e, int *bits);
        static  int32_t word0(double d);
        static  double  setWord0(double d, int32_t i);
        static  int32_t word1(double d);
        static  JSBigInteger
                        pow5mult(JSContext *cx, JSBigInteger &b, int k);
        static  jsBool_t
                        roundOff(JSStringBuffer *buf);

    public:
        static jsString_t
                        JS_dtobasestr(JSContext *cx, int base, double d);
        static int      JS_dtoa(JSContext *cx, double d, int mode,
                                jsBool_t biasUp, int ndigits, jsBool_t *sign,
                                JSStringBuffer *buf);
        static void     JS_dtostr(JSContext *cx, JSStringBuffer *buffer,
                                int mode, int precision, double d);
};

#endif /* _JS_DTOA_H_ */

#endif /* DTOA */

