Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.jackson.core.io;
  
  public final class NumberOutput
  {
      private final static char NULL_CHAR = (char) 0;
  
      private static int MILLION = 1000000;
      private static int BILLION = 1000000000;
      private static long TEN_BILLION_L = 10000000000L;
     private static long THOUSAND_L = 1000L;
 
     private static long MIN_INT_AS_LONG = (long.;
     private static long MAX_INT_AS_LONG = (long.;
 
     final static String SMALLEST_LONG = String.valueOf(.);
 
     final static char[] LEADING_TRIPLETS = new char[4000];
     final static char[] FULL_TRIPLETS = new char[4000];
     static {
         /* Let's fill it with NULLs for ignorable leading digits,
          * and digit chars for others
          */
         int ix = 0;
         for (int i1 = 0; i1 < 10; ++i1) {
             char f1 = (char) ('0' + i1);
             char l1 = (i1 == 0) ?  : f1;
             for (int i2 = 0; i2 < 10; ++i2) {
                 char f2 = (char) ('0' + i2);
                 char l2 = (i1 == 0 && i2 == 0) ?  : f2;
                 for (int i3 = 0; i3 < 10; ++i3) {
                     // Last is never to be empty
                     char f3 = (char) ('0' + i3);
                     [ix] = l1;
                     [ix+1] = l2;
                     [ix+2] = f3;
                     [ix] = f1;
                     [ix+1] = f2;
                     [ix+2] = f3;
                     ix += 4;
                 }
             }
         }
     }
 
     final static byte[] FULL_TRIPLETS_B = new byte[4000];
     static {
         for (int i = 0; i < 4000; ++i) {
             [i] = (byte[i];
         }
     }
     
     final static String[] sSmallIntStrs = new String[] {
         "0","1","2","3","4","5","6","7","8","9","10"
     };
     final static String[] sSmallIntStrs2 = new String[] {
         "-1","-2","-3","-4","-5","-6","-7","-8","-9","-10"
     };
 
     /*
     /**********************************************************
     /* Efficient serialization methods using raw buffers
     /**********************************************************
      */

    

Returns:
Offset within buffer after outputting int
 
     public static int outputInt(int valuechar[] bufferint offset)
     {
         if (value < 0) {
             if (value == .) {
                 /* Special case: no matching positive value within range;
                  * let's then "upgrade" to long and output as such.
                  */
                 return outputLong((longvaluebufferoffset);
             }
             buffer[offset++] = '-';
             value = -value;
         }
 
         if (value < ) { // at most 2 triplets...
             if (value < 1000) {
                 if (value < 10) {
                     buffer[offset++] = (char) ('0' + value);
                 } else {
                     offset = outputLeadingTriplet(valuebufferoffset);
                 }
             } else {
                 int thousands = value / 1000;
                 value -= (thousands * 1000); // == value % 1000
                 offset = outputLeadingTriplet(thousandsbufferoffset);
                 offset = outputFullTriplet(valuebufferoffset);
             }
             return offset;
         }
 
         // ok, all 3 triplets included
         /* Let's first hand possible billions separately before
          * handling 3 triplets. This is possible since we know we
         * can have at most '2' as billion count.
         */
        boolean hasBillions = (value >= );
        if (hasBillions) {
            value -= ;
            if (value >= ) {
                value -= ;
                buffer[offset++] = '2';
            } else {
                buffer[offset++] = '1';
            }
        }
        int newValue = value / 1000;
        int ones = (value - (newValue * 1000)); // == value % 1000
        value = newValue;
        newValue /= 1000;
        int thousands = (value - (newValue * 1000));
        
        // value now has millions, which have 1, 2 or 3 digits
        if (hasBillions) {
            offset = outputFullTriplet(newValuebufferoffset);
        } else {
            offset = outputLeadingTriplet(newValuebufferoffset);
        }
        offset = outputFullTriplet(thousandsbufferoffset);
        offset = outputFullTriplet(onesbufferoffset);
        return offset;
    }
    public static int outputInt(int valuebyte[] bufferint offset)
    {
        if (value < 0) {
            if (value == .) {
                return outputLong((longvaluebufferoffset);
            }
            buffer[offset++] = '-';
            value = -value;
        }
        if (value < ) { // at most 2 triplets...
            if (value < 1000) {
                if (value < 10) {
                    buffer[offset++] = (byte) ('0' + value);
                } else {
                    offset = outputLeadingTriplet(valuebufferoffset);
                }
            } else {
                int thousands = value / 1000;
                value -= (thousands * 1000); // == value % 1000
                offset = outputLeadingTriplet(thousandsbufferoffset);
                offset = outputFullTriplet(valuebufferoffset);
            }
            return offset;
        }
        boolean hasBillions = (value >= );
        if (hasBillions) {
            value -= ;
            if (value >= ) {
                value -= ;
                buffer[offset++] = '2';
            } else {
                buffer[offset++] = '1';
            }
        }
        int newValue = value / 1000;
        int ones = (value - (newValue * 1000)); // == value % 1000
        value = newValue;
        newValue /= 1000;
        int thousands = (value - (newValue * 1000));
        
        if (hasBillions) {
            offset = outputFullTriplet(newValuebufferoffset);
        } else {
            offset = outputLeadingTriplet(newValuebufferoffset);
        }
        offset = outputFullTriplet(thousandsbufferoffset);
        offset = outputFullTriplet(onesbufferoffset);
        return offset;
    }
    
    

Returns:
Offset within buffer after outputting int
    public static int outputLong(long valuechar[] bufferint offset)
    {
        // First: does it actually fit in an int?
        if (value < 0L) {
            /* MIN_INT is actually printed as long, just because its
             * negation is not an int but long
             */
            if (value > ) {
                return outputInt((intvaluebufferoffset);
            }
            if (value == .) {
                // Special case: no matching positive value within range
                int len = .length();
                .getChars(0, lenbufferoffset);
                return (offset + len);
            }
            buffer[offset++] = '-';
            value = -value;
        } else {
            if (value <= ) {
                return outputInt((intvaluebufferoffset);
            }
        }
        /* Ok: real long print. Need to first figure out length
         * in characters, and then print in from end to beginning
         */
        int origOffset = offset;
        offset += calcLongStrLength(value);
        int ptr = offset;
        // First, with long arithmetics:
        while (value > ) { // full triplet
            ptr -= 3;
            long newValue = value / ;
            int triplet = (int) (value - newValue * );
            outputFullTriplet(tripletbufferptr);
            value = newValue;
        }
        // Then with int arithmetics:
        int ivalue = (intvalue;
        while (ivalue >= 1000) { // still full triplet
            ptr -= 3;
            int newValue = ivalue / 1000;
            int triplet = ivalue - (newValue * 1000);
            outputFullTriplet(tripletbufferptr);
            ivalue = newValue;
        }
        // And finally, if anything remains, partial triplet
        outputLeadingTriplet(ivaluebufferorigOffset);
        return offset;
    }
    public static int outputLong(long valuebyte[] bufferint offset)
    {
        if (value < 0L) {
            if (value > ) {
                return outputInt((intvaluebufferoffset);
            }
            if (value == .) {
                // Special case: no matching positive value within range
                int len = .length();
                for (int i = 0; i < len; ++i) {
                    buffer[offset++] = (byte.charAt(i);
                }
                return offset;
            }
            buffer[offset++] = '-';
            value = -value;
        } else {
            if (value <= ) {
                return outputInt((intvaluebufferoffset);
            }
        }
        int origOffset = offset;
        offset += calcLongStrLength(value);
        int ptr = offset;
        // First, with long arithmetics:
        while (value > ) { // full triplet
            ptr -= 3;
            long newValue = value / ;
            int triplet = (int) (value - newValue * );
            outputFullTriplet(tripletbufferptr);
            value = newValue;
        }
        // Then with int arithmetics:
        int ivalue = (intvalue;
        while (ivalue >= 1000) { // still full triplet
            ptr -= 3;
            int newValue = ivalue / 1000;
            int triplet = ivalue - (newValue * 1000);
            outputFullTriplet(tripletbufferptr);
            ivalue = newValue;
        }
        outputLeadingTriplet(ivaluebufferorigOffset);
        return offset;
    }
    
    /*
    /**********************************************************
    /* Secondary convenience serialization methods
    /**********************************************************
     */
    /* !!! 05-Aug-2008, tatus: Any ways to further optimize
     *   these? (or need: only called by diagnostics methods?)
     */
    public static String toString(int value)
    {
        // Lookup table for small values
        if (value < .) {
            if (value >= 0) {
                return [value];
            }
            int v2 = -value - 1;
            if (v2 < .) {
                return [v2];
            }
        }
        return Integer.toString(value);
    }
    public static String toString(long value)
    {
        if (value <= . &&
            value >= .) {
            return toString((intvalue);
        }
        return Long.toString(value);
    }
    public static String toString(double value)
    {
        return Double.toString(value);
    }
    /*
    /**********************************************************
    /* Internal methods
    /**********************************************************
     */
    private static int outputLeadingTriplet(int tripletchar[] bufferint offset)
    {
        int digitOffset = (triplet << 2);
        char c = [digitOffset++];
        if (c != ) {
            buffer[offset++] = c;
        }
        c = [digitOffset++];
        if (c != ) {
            buffer[offset++] = c;
        }
        // Last is required to be non-empty
        buffer[offset++] = [digitOffset];
        return offset;
    }
    private static int outputLeadingTriplet(int tripletbyte[] bufferint offset)
    {
        int digitOffset = (triplet << 2);
        char c = [digitOffset++];
        if (c != ) {
            buffer[offset++] = (bytec;
        }
        c = [digitOffset++];
        if (c != ) {
            buffer[offset++] = (bytec;
        }
        // Last is required to be non-empty
        buffer[offset++] = (byte[digitOffset];
        return offset;
    }
    
    private static int outputFullTriplet(int tripletchar[] bufferint offset)
    {
        int digitOffset = (triplet << 2);
        buffer[offset++] = [digitOffset++];
        buffer[offset++] = [digitOffset++];
        buffer[offset++] = [digitOffset];
        return offset;
    }
    private static int outputFullTriplet(int tripletbyte[] bufferint offset)
    {
        int digitOffset = (triplet << 2);
        buffer[offset++] = [digitOffset++];
        buffer[offset++] = [digitOffset++];
        buffer[offset++] = [digitOffset];
        return offset;
    }
    
    

Pre-conditions: posValue is positive, and larger than Integer.MAX_VALUE (about 2 billions).

    private static int calcLongStrLength(long posValue)
    {
        int len = 10;
        long comp = ;
        // 19 is longest, need to worry about overflow
        while (posValue >= comp) {
            if (len == 19) {
                break;
            }
            ++len;
            comp = (comp << 3) + (comp << 1); // 10x
        }
        return len;
    }
New to GrepCode? Check out our FAQ X