public static int toDecimalDigits(LargeUInt f, int e, int p,
                                      char[] digits, int offset,
                                      int maxDigits, int maxFractDigits,
                                      int roundMode)
    {
        if (f.isZero() || maxDigits == 0) {
            return 0;
        }

        LargeUInt S = new LargeUInt();
        S.setValue(1);
        LargeUInt R = new LargeUInt(f);
        LargeUInt mlo = new LargeUInt();
        mlo.setValue(1);
        
        if (p > e) {
            S.shiftLeft(p - e);
        }
        else {
            R.shiftLeft(e - p);
            mlo.shiftLeft(e - p);
        }

        LargeUInt mhi = mlo;

        // Begin Simple-Fixup

        LargeUInt temp = new LargeUInt();
        temp.setValue(1);
        temp.shiftLeft(p - 1);

        if (f.compare(temp) == 0) {
            R.shiftLeft(1);
            S.shiftLeft(1);
            // Set this again later to be 2 * mlo.
            mhi = null;
        }
        
        int k = 0;
        temp.setValue(S);
        temp.add(9);
        temp.divideByTen();
        while (R.compare(temp) < 0) {
            k--;
            R.multiplyByTen();
        }

        if (k < 0) {
            mlo.multiplyByTenthPower(-k);
        }

        if (mhi == null) {
            mhi = new LargeUInt(mlo);
            mhi.shiftLeft(1);
        }

        temp.setValue(R);
        temp.shiftLeft(1);
        temp.add(mhi);
        LargeUInt S2 = new LargeUInt(S);
        S2.shiftLeft(1);
        int oldK = k;
        while (S2.compare(temp) < 0) {
            S2.multiplyByTen();
            k++;
        }

        if (k > oldK) {
            S.multiplyByTenthPower(k - oldK);
        }

        // End Simple-Fixup

        int cursor = offset;
        int limit = k + maxFractDigits;
        if (limit > maxDigits) {
            limit = offset + maxDigits;
        }
        else {
            limit += offset;
        }

        if (limit <= offset) {
            if (limit == offset) {
                temp.setValue(R);
                temp.shiftLeft(1);
                if (temp.compare(S) >= 0) {
                    digits[cursor++] = '1';
                    k++;
                }
            }
            return (k << 16) | (cursor - offset);
        }

        if (roundMode == ROUND_HALF_UP_DECIMAL) {
            // Emit one additional digit to be tested.
            limit++;
        }

        LargeUInt temp2 = f;

        while (true) {
            R.multiplyByTen();
            digits[cursor++] = (char)(R.divideClose(S) + '0');
            
            if (mlo == mhi) {
                mlo.multiplyByTen();
            }
            else {
                mlo.multiplyByTen();
                mhi.multiplyByTen();
            }
            
            temp.setValue(R);
            temp.shiftLeft(1);
            temp2.setValue(S2);
            temp2.subtract(mhi);
            
            if (temp.compare(mlo) < 0) {
                if (temp.compare(temp2) > 0) {
                    // low and high
                    if (temp.compare(S) >= 0) {
                        k += increment(digits, offset, cursor);
                    }
                }
                break;
            }
            else if (temp.compare(temp2) > 0) {
                // high and not low
                k += increment(digits, offset, cursor);
                break;
            }
            
            if (cursor >= limit) {
                if (roundMode != ROUND_HALF_UP_DECIMAL) {
                    if (temp.compare(S) >= 0) {
                        k += increment(digits, offset, cursor);
                    }
                }
                break;
            }
        }

        if (cursor >= limit && roundMode == ROUND_HALF_UP_DECIMAL) {
            // Chop off extra digit.
            cursor--;
            if (digits[cursor] >= '5') {
                k += increment(digits, offset, cursor);
            }
        }

        return (k << 16) | (cursor - offset);
    }
public static int toDecimalDigits ( LargeUInt f , int e , int p , char [ ] digits , int offset , int maxDigits , int maxFractDigits , int roundMode ) { if ( f . isZero ( ) || maxDigits == 0 ) { return 0 ; } LargeUInt S = new LargeUInt ( ) ; S . setValue ( 1 ) ; LargeUInt R = new LargeUInt ( f ) ; LargeUInt mlo = new LargeUInt ( ) ; mlo . setValue ( 1 ) ; if ( p > e ) { S . shiftLeft ( p - e ) ; } else { R . shiftLeft ( e - p ) ; mlo . shiftLeft ( e - p ) ; } LargeUInt mhi = mlo ; LargeUInt temp = new LargeUInt ( ) ; temp . setValue ( 1 ) ; temp . shiftLeft ( p - 1 ) ; if ( f . compare ( temp ) == 0 ) { R . shiftLeft ( 1 ) ; S . shiftLeft ( 1 ) ; mhi = null ; } int k = 0 ; temp . setValue ( S ) ; temp . add ( 9 ) ; temp . divideByTen ( ) ; while ( R . compare ( temp ) < 0 ) { k -- ; R . multiplyByTen ( ) ; } if ( k < 0 ) { mlo . multiplyByTenthPower ( - k ) ; } if ( mhi == null ) { mhi = new LargeUInt ( mlo ) ; mhi . shiftLeft ( 1 ) ; } temp . setValue ( R ) ; temp . shiftLeft ( 1 ) ; temp . add ( mhi ) ; LargeUInt S2 = new LargeUInt ( S ) ; S2 . shiftLeft ( 1 ) ; int oldK = k ; while ( S2 . compare ( temp ) < 0 ) { S2 . multiplyByTen ( ) ; k ++ ; } if ( k > oldK ) { S . multiplyByTenthPower ( k - oldK ) ; } int cursor = offset ; int limit = k + maxFractDigits ; if ( limit > maxDigits ) { limit = offset + maxDigits ; } else { limit += offset ; } if ( limit <= offset ) { if ( limit == offset ) { temp . setValue ( R ) ; temp . shiftLeft ( 1 ) ; if ( temp . compare ( S ) >= 0 ) { digits [ cursor ++ ] = '1' ; k ++ ; } } return ( k << 16 ) | ( cursor - offset ) ; } if ( roundMode == ROUND_HALF_UP_DECIMAL ) { limit ++ ; } LargeUInt temp2 = f ; while ( true ) { R . multiplyByTen ( ) ; digits [ cursor ++ ] = ( char ) ( R . divideClose ( S ) + '0' ) ; if ( mlo == mhi ) { mlo . multiplyByTen ( ) ; } else { mlo . multiplyByTen ( ) ; mhi . multiplyByTen ( ) ; } temp . setValue ( R ) ; temp . shiftLeft ( 1 ) ; temp2 . setValue ( S2 ) ; temp2 . subtract ( mhi ) ; if ( temp . compare ( mlo ) < 0 ) { if ( temp . compare ( temp2 ) > 0 ) { if ( temp . compare ( S ) >= 0 ) { k += increment ( digits , offset , cursor ) ; } } break ; } else if ( temp . compare ( temp2 ) > 0 ) { k += increment ( digits , offset , cursor ) ; break ; } if ( cursor >= limit ) { if ( roundMode != ROUND_HALF_UP_DECIMAL ) { if ( temp . compare ( S ) >= 0 ) { k += increment ( digits , offset , cursor ) ; } } break ; } } if ( cursor >= limit && roundMode == ROUND_HALF_UP_DECIMAL ) { cursor -- ; if ( digits [ cursor ] >= '5' ) { k += increment ( digits , offset , cursor ) ; } } return ( k << 16 ) | ( cursor - offset ) ; }
Produces decimal digits for binary floating point values greater than
zero.

@param f floating point mantissa <b>(value is destroyed)</b>
@param e floating point exponent
@param p floating point precision (number of bits)
@param digits buffer to receive decimal digits
@param offset offset into digit buffer
@param maxDigits maximum number of digits to produce
@param maxFractDigits maximum number of fractional digits to produce
@param roundMode i.e. ROUND_HALF_UP
@return Upper 16 bits: decimal point offset; lower 16 bits: number of
digits produced