All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.javascript.jscomp.base.JSCompDoubles Maven / Gradle / Ivy

Go to download

Closure Compiler is a JavaScript optimizing compiler. It parses your JavaScript, analyzes it, removes dead code and rewrites and minimizes what's left. It also checks syntax, variable references, and types, and warns about common JavaScript pitfalls. It is used in many of Google's JavaScript apps, including Gmail, Google Web Search, Google Maps, and Google Docs.

There is a newer version: v20240317
Show newest version
/*
 * Copyright 2020 The Closure Compiler Authors.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.javascript.jscomp.base;

import static com.google.common.base.Preconditions.checkState;

/** Basic double functions used by JSComp. */
public final class JSCompDoubles {

  /**
   * Can a 32 bit int exactly represent `x`?
   *
   * 

Many double values are not exact integers. Many that are integers are too large to fit into * a Java int. * *

This function does not guarantee that a value can be round-tripped from double to int to * double and have an identical bit pattern. Notably, 0.0 and -0.0 both represent exactly 0. */ public static boolean isExactInt32(double x) { return !Double.isNaN(x) && ((double) ((int) x)) == x; } /** * Can a 64 bit int exactly represent `x`? * *

Many double values are not exact integers. Many that are integers are too large to fit into * a Java long. * *

This function does not guarantee that a value can be round-tripped from double to long to * double and have an identical bit pattern. Notably, 0.0 and -0.0 both represent exactly 0. */ public static boolean isExactInt64(double x) { return !Double.isNaN(x) && ((double) ((long) x)) == x; } /** * Does `x` exactly represent an value with no fractional part? * *

The value may be too large to fit in a primitive integral type, such as long. * *

Returns false for NaN and Infinity. * *

This should behave identically to Guava {@code DoubleMath.isMathematicalInteger} but is J2CL * compatible. */ public static boolean isMathematicalInteger(double x) { return x % 1.0 == 0.0; } /** * Does `x` have precision down to the "ones column"? * *

A double can hold exact integer values that are very large, but to do so it may loose * precision at the scale of "ones". That is "largeDouble + 1.0 == largeDouble" may be true. * *

Returns false for NaN and Infinity. */ public static boolean isAtLeastIntegerPrecision(double x) { // It's possible for a JVM to use floating-point values with more than 53 bits of precision, // but we have to be conservative. return Math.abs(x) < POW_2_53; } /** * Does `x` carry a negative sign? * *

Because -0.0 == 0.0, it is not enough to check `x < 0.0` to determine if a double is * negative. This function identifies the -0.0 case. * * @throws if passed NaN since NaNs are neither positive nor negative. */ public static boolean isNegative(double x) { checkState(!Double.isNaN(x)); return Double.compare(0.0, x) > 0; } /** * Does `x` not carry a negative sign? * *

Because -0.0 == 0.0, it is not enough to check `x < 0.0` to determine if a double is * negative. This function identifies the -0.0 case. * * @throws if passed NaN since NaNs are neither positive nor negative. */ public static boolean isPositive(double x) { return !isNegative(x); } /** Is `x` positive or negative zero? */ public static boolean isEitherZero(double x) { return x == 0.0; } /** * The ECMAScript ToInt32 abstract operation. * *

See https://262.ecma-international.org/5.1/#sec-9.5 */ public static int ecmascriptToInt32(double number) { // Fast path for most common case. Also covers -0.0 if (isExactInt32(number)) { return (int) number; } // Step 2 if (Double.isNaN(number) || Double.isInfinite(number)) { return 0; } // Step 3 double posInt = (number >= 0) ? Math.floor(number) : Math.ceil(number); /** * Step 4 * *

Afer modding, the value must fit into a long, but not necessarily an int. * *

If value produced by modding is negative, the spec says to add 2^32 so that `int32bit` is * positive. However, that addition doesn't affect the trailing 32 bits of the `int32bit`, which * are the only ones that matter. */ long int32bit = (long) (posInt % POW_2_32); /** * Step 5 * *

The instructions in the spec are equivalent to interpreting the last 32 bits of `int32bit` * as a 2s-compliment integer, which is exactly the representation Java uses for int. */ return (int) int32bit; } /** * The ECMAScript ToUint32 abstract operation. * *

Java has no uint types, so the caller must remember to treat the returned bits as a uint. * *

See https://262.ecma-international.org/5.1/#sec-9.6 */ public static int ecmascriptToUint32(double number) { return ecmascriptToInt32(number); } private static final double POW_2_32 = Math.pow(2, 32); private static final double POW_2_53 = Math.pow(2, 53); private JSCompDoubles() { throw new AssertionError(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy