/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
*
* Subject to the condition set forth below, permission is hereby granted to any
* person obtaining a copy of this software, associated documentation and/or
* data (collectively the "Software"), free of charge and under any and all
* copyright rights in the Software, and any and all patent rights owned or
* freely licensable by each licensor hereunder covering either (i) the
* unmodified Software as contributed to or provided by such licensor, or (ii)
* the Larger Works (as defined below), to deal in both
*
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
* one is included with the Software each a "Larger Work" to which the Software
* is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy, create
* derivative works of, display, perform, and distribute the Software and make,
* use, sell, offer for sale, import, export, have made, and have sold the
* Software and the Larger Work(s), and to sublicense the foregoing rights on
* either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or at a
* minimum a reference to the UPL must be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
// This file is available under and governed by the Universal Permissive License
// (UPL) 1.0 only. However, the following notice accompanied the original version
// of this file:
//
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.oracle.truffle.js.runtime.doubleconv;
This class provides the public API for the double conversion package.
Using double-conversion version 3.1.5.
/**
* This class provides the public API for the double conversion package.
*
* Using double-conversion version 3.1.5.
*/
public final class DoubleConversion {
private DoubleConversion() {
// should not be constructed
}
private static final int kMaxFixedDigitsBeforePoint = 60;
private static final int kMaxFixedDigitsAfterPoint = 60;
private static final int kMaxExponentialDigits = 120;
private static final int kBase10MaximalLength = 17;
Converts a double number to its shortest string representation.
Params: - value – number to convert
Returns: formatted number
/**
* Converts a double number to its shortest string representation.
*
* @param value number to convert
* @return formatted number
*/
public static String toShortest(final double value) {
assert Double.isFinite(value) : value;
final DtoaBuffer buffer = new DtoaBuffer(FastDtoa.kFastDtoaMaximalLength);
dtoaShortest(value, buffer);
return buffer.format(DtoaMode.SHORTEST, 0);
}
private static void dtoaShortest(final double value, final DtoaBuffer buffer) {
final double absValue = Math.abs(value);
if (value < 0) {
buffer.isNegative = true;
}
if (value == 0) {
buffer.append('0');
buffer.decimalPoint = 1;
} else if (!fastDtoaShortest(absValue, buffer)) {
buffer.reset();
bignumDtoa(absValue, DtoaMode.SHORTEST, 0, buffer);
}
}
Converts a double number to a string representation with a fixed number of digits after the
decimal point.
Params: - value – number to convert.
- requestedDigits – number of digits after decimal point
Returns: formatted number
/**
* Converts a double number to a string representation with a fixed number of digits after the
* decimal point.
*
* @param value number to convert.
* @param requestedDigits number of digits after decimal point
* @return formatted number
*/
public static String toFixed(final double value, final int requestedDigits) {
assert Double.isFinite(value) : value;
final DtoaBuffer buffer = new DtoaBuffer(kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint);
final double absValue = Math.abs(value);
if (value < 0) {
buffer.isNegative = true;
}
if (value == 0) {
buffer.append('0');
buffer.decimalPoint = 1;
} else if (!fixedDtoa(absValue, requestedDigits, buffer)) {
buffer.reset();
bignumDtoa(absValue, DtoaMode.FIXED, requestedDigits, buffer);
}
return buffer.format(DtoaMode.FIXED, requestedDigits);
}
Converts a double number to a string representation with a fixed number of digits.
Params: - value – number to convert
- precision – number of digits to create
Returns: formatted number
/**
* Converts a double number to a string representation with a fixed number of digits.
*
* @param value number to convert
* @param precision number of digits to create
* @return formatted number
*/
public static String toPrecision(final double value, final int precision) {
assert Double.isFinite(value) : value;
final DtoaBuffer buffer = new DtoaBuffer(precision);
dtoaPrecision(value, precision, buffer);
return buffer.format(DtoaMode.PRECISION, 0);
}
private static void dtoaPrecision(final double value, final int precision, final DtoaBuffer buffer) {
final double absValue = Math.abs(value);
if (value < 0) {
buffer.isNegative = true;
}
if (value == 0) {
for (int i = 0; i < precision; i++) {
buffer.append('0');
}
buffer.decimalPoint = 1;
} else if (!fastDtoaCounted(absValue, precision, buffer)) {
buffer.reset();
bignumDtoa(absValue, DtoaMode.PRECISION, precision, buffer);
}
}
Converts a double number to a string representation using the BignumDtoa
algorithm and the specified conversion mode and number of digits. Params: - v – number to convert
- mode – conversion mode
- digits – number of digits
- buffer – buffer to use
/**
* Converts a double number to a string representation using the {@code BignumDtoa} algorithm
* and the specified conversion mode and number of digits.
*
* @param v number to convert
* @param mode conversion mode
* @param digits number of digits
* @param buffer buffer to use
*/
public static void bignumDtoa(final double v, final DtoaMode mode, final int digits, final DtoaBuffer buffer) {
assert v > 0 && !Double.isNaN(v) && !Double.isInfinite(v) : v;
BignumDtoa.bignumDtoa(v, mode, digits, buffer);
}
Converts a double number to its shortest string representation using the FastDtoa
algorithm. Params: - v – number to convert
- buffer – buffer to use
Returns: true if conversion succeeded
/**
* Converts a double number to its shortest string representation using the {@code FastDtoa}
* algorithm.
*
* @param v number to convert
* @param buffer buffer to use
* @return true if conversion succeeded
*/
public static boolean fastDtoaShortest(final double v, final DtoaBuffer buffer) {
assert v > 0 && !Double.isNaN(v) && !Double.isInfinite(v) : v;
return FastDtoa.grisu3(v, buffer);
}
Converts a double number to a string representation with the given number of digits using the FastDtoa
algorithm. Params: - v – number to convert
- precision – number of digits to generate
- buffer – buffer to use
Returns: true if conversion succeeded
/**
* Converts a double number to a string representation with the given number of digits using the
* {@code FastDtoa} algorithm.
*
* @param v number to convert
* @param precision number of digits to generate
* @param buffer buffer to use
* @return true if conversion succeeded
*/
public static boolean fastDtoaCounted(final double v, final int precision, final DtoaBuffer buffer) {
assert v > 0 && !Double.isNaN(v) && !Double.isInfinite(v) : v;
return FastDtoa.grisu3Counted(v, precision, buffer);
}
Converts a double number to a string representation with a fixed number of digits after the decimal point using the FixedDtoa
algorithm. Params: - v – number to convert.
- digits – number of digits after the decimal point
- buffer – buffer to use
Returns: true if conversion succeeded
/**
* Converts a double number to a string representation with a fixed number of digits after the
* decimal point using the {@code FixedDtoa} algorithm.
*
* @param v number to convert.
* @param digits number of digits after the decimal point
* @param buffer buffer to use
* @return true if conversion succeeded
*/
public static boolean fixedDtoa(final double v, final int digits, final DtoaBuffer buffer) {
assert v > 0 && !Double.isNaN(v) && !Double.isInfinite(v) : v;
return FixedDtoa.fastFixedDtoa(v, digits, buffer);
}
Computes a representation in exponential format with requestedDigits after the decimal point.
The last emitted digit is rounded. If requestedDigits equals -1, then the shortest
exponential representation is computed.
Params: - value – number to convert
- requestedDigits – number of digits after the decimal point
Returns: true if conversion succeeded
/**
* Computes a representation in exponential format with requestedDigits after the decimal point.
* The last emitted digit is rounded. If requestedDigits equals -1, then the shortest
* exponential representation is computed.
*
* @param value number to convert
* @param requestedDigits number of digits after the decimal point
* @return true if conversion succeeded
*/
public static String toExponential(double value, int requestedDigits) {
return toExponential(value, requestedDigits, true);
}
Computes a representation in exponential format with requestedDigits after the decimal point.
The last emitted digit is rounded. If requestedDigits equals -1, then the shortest
exponential representation is computed.
Params: - value – number to convert
- requestedDigits – number of digits after the decimal point
- uniqueZero – "-0.0" is converted to "0.0".
Returns: true if conversion succeeded
/**
* Computes a representation in exponential format with requestedDigits after the decimal point.
* The last emitted digit is rounded. If requestedDigits equals -1, then the shortest
* exponential representation is computed.
*
* @param value number to convert
* @param requestedDigits number of digits after the decimal point
* @param uniqueZero "-0.0" is converted to "0.0".
* @return true if conversion succeeded
*/
public static String toExponential(double value, int requestedDigits, boolean uniqueZero) {
assert Double.isFinite(value) : value;
assert !(requestedDigits < -1 || requestedDigits > kMaxExponentialDigits) : requestedDigits;
boolean sign = value < 0.0;
double absValue = Math.abs(value);
// Add space for digit before the decimal point.
int kDecimalRepCapacity = kMaxExponentialDigits + 1;
assert kDecimalRepCapacity > kBase10MaximalLength;
final DtoaBuffer buffer = new DtoaBuffer(kDecimalRepCapacity);
if (requestedDigits == -1) {
dtoaShortest(absValue, buffer);
} else {
dtoaPrecision(absValue, requestedDigits + 1, buffer);
assert buffer.getLength() <= requestedDigits + 1;
for (int i = buffer.getLength(); i < requestedDigits + 1; ++i) {
buffer.append('0');
}
assert buffer.getLength() == requestedDigits + 1;
}
StringBuilder resultBuilder = new StringBuilder();
if (sign && (value != 0.0 || !uniqueZero)) {
resultBuilder.append('-');
}
buffer.toExponentialFormat(resultBuilder);
return resultBuilder.toString();
}
}