1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 // This file is available under and governed by the GNU General Public
  27 // License version 2 only, as published by the Free Software Foundation.
  28 // However, the following notice accompanied the original version of this
  29 // file:
  30 //
  31 // Copyright 2011 the V8 project authors. All rights reserved.
  32 // Redistribution and use in source and binary forms, with or without
  33 // modification, are permitted provided that the following conditions are
  34 // met:
  35 //
  36 //     * Redistributions of source code must retain the above copyright
  37 //       notice, this list of conditions and the following disclaimer.
  38 //     * Redistributions in binary form must reproduce the above
  39 //       copyright notice, this list of conditions and the following
  40 //       disclaimer in the documentation and/or other materials provided
  41 //       with the distribution.
  42 //     * Neither the name of Google Inc. nor the names of its
  43 //       contributors may be used to endorse or promote products derived
  44 //       from this software without specific prior written permission.
  45 //
  46 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  47 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  48 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  49 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  50 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  51 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  52 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  53 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  54 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  55 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  56 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  57 
  58 package jdk.nashorn.internal.runtime.doubleconv;
  59 
  60 /**
  61  * This class provides the public API for the double conversion package.
  62  */
  63 public final class DoubleConversion {
  64 
  65     private final static int BUFFER_LENGTH = 30;
  66 
  67     /**
  68      * Converts a double number to its shortest string representation.
  69      *
  70      * @param value number to convert
  71      * @return formatted number
  72      */
  73     public static String toShortestString(final double value) {
  74         final DtoaBuffer buffer = new DtoaBuffer(FastDtoa.kFastDtoaMaximalLength);
  75         final double absValue = Math.abs(value);
  76 
  77         if (value < 0) {
  78             buffer.isNegative = true;
  79         }
  80 
  81         if (!fastDtoaShortest(absValue, buffer)) {
  82             buffer.reset();
  83             bignumDtoa(absValue, DtoaMode.SHORTEST, 0, buffer);
  84         }
  85 
  86         return buffer.format(DtoaMode.SHORTEST, 0);
  87     }
  88 
  89     /**
  90      * Converts a double number to a string representation with a fixed number of digits
  91      * after the decimal point.
  92      *
  93      * @param value number to convert.
  94      * @param requestedDigits number of digits after decimal point
  95      * @return formatted number
  96      */
  97     public static String toFixed(final double value, final int requestedDigits) {
  98         final DtoaBuffer buffer = new DtoaBuffer(BUFFER_LENGTH);
  99         final double absValue = Math.abs(value);
 100 
 101         if (value < 0) {
 102             buffer.isNegative = true;
 103         }
 104 
 105         if (value == 0) {
 106             buffer.append('0');
 107             buffer.decimalPoint = 1;
 108         } else if (!fixedDtoa(absValue, requestedDigits, buffer)) {
 109             buffer.reset();
 110             bignumDtoa(absValue, DtoaMode.FIXED, requestedDigits, buffer);
 111         }
 112 
 113         return buffer.format(DtoaMode.FIXED, requestedDigits);
 114     }
 115 
 116     /**
 117      * Converts a double number to a string representation with a fixed number of digits.
 118      *
 119      * @param value number to convert
 120      * @param precision number of digits to create
 121      * @return formatted number
 122      */
 123     public static String toPrecision(final double value, final int precision) {
 124         final DtoaBuffer buffer = new DtoaBuffer(precision);
 125         final double absValue = Math.abs(value);
 126 
 127         if (value < 0) {
 128             buffer.isNegative = true;
 129         }
 130 
 131         if (value == 0) {
 132             for (int i = 0; i < precision; i++) {
 133                 buffer.append('0');
 134             }
 135             buffer.decimalPoint = 1;
 136 
 137         } else if (!fastDtoaCounted(absValue, precision, buffer)) {
 138             buffer.reset();
 139             bignumDtoa(absValue, DtoaMode.PRECISION, precision, buffer);
 140         }
 141 
 142         return buffer.format(DtoaMode.PRECISION, 0);
 143     }
 144 
 145     /**
 146      * Converts a double number to a string representation using the
 147      * {@code BignumDtoa} algorithm and the specified conversion mode
 148      * and number of digits.
 149      *
 150      * @param v number to convert
 151      * @param mode conversion mode
 152      * @param digits number of digits
 153      * @param buffer buffer to use
 154      */
 155     public static void bignumDtoa(final double v, final DtoaMode mode, final int digits, final DtoaBuffer buffer) {
 156         assert(v > 0);
 157         assert(!Double.isNaN(v));
 158         assert(!Double.isInfinite(v));
 159 
 160         BignumDtoa.bignumDtoa(v, mode, digits, buffer);
 161     }
 162 
 163     /**
 164      * Converts a double number to its shortest string representation
 165      * using the {@code FastDtoa} algorithm.
 166      *
 167      * @param v number to convert
 168      * @param buffer buffer to use
 169      * @return true if conversion succeeded
 170      */
 171     public static boolean fastDtoaShortest(final double v, final DtoaBuffer buffer) {
 172         assert(v > 0);
 173         assert(!Double.isNaN(v));
 174         assert(!Double.isInfinite(v));
 175 
 176         return FastDtoa.grisu3(v, buffer);
 177     }
 178 
 179     /**
 180      * Converts a double number to a string representation with the
 181      * given number of digits using the {@code FastDtoa} algorithm.
 182      *
 183      * @param v number to convert
 184      * @param precision number of digits to generate
 185      * @param buffer buffer to use
 186      * @return true if conversion succeeded
 187      */
 188     public static boolean fastDtoaCounted(final double v, final int precision, final DtoaBuffer buffer) {
 189         assert(v > 0);
 190         assert(!Double.isNaN(v));
 191         assert(!Double.isInfinite(v));
 192 
 193         return FastDtoa.grisu3Counted(v, precision, buffer);
 194     }
 195 
 196     /**
 197      * Converts a double number to a string representation with a
 198      * fixed number of digits after the decimal point using the
 199      * {@code FixedDtoa} algorithm.
 200      *
 201      * @param v number to convert.
 202      * @param digits number of digits after the decimal point
 203      * @param buffer buffer to use
 204      * @return true if conversion succeeded
 205      */
 206     public static boolean fixedDtoa(final double v, final int digits, final DtoaBuffer buffer) {
 207         assert(v > 0);
 208         assert(!Double.isNaN(v));
 209         assert(!Double.isInfinite(v));
 210 
 211         return FixedDtoa.fastFixedDtoa(v, digits, buffer);
 212     }
 213 
 214 }