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

java.lang.Double Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2011-2014 Fernando Petrola
 * 
 *  This file is part of Dragome SDK.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 ******************************************************************************/
package java.lang;

import javascript.Utils;

import com.dragome.commons.javascript.ScriptHelper;

/*
 * Copyright (c) 2006 j2js.com,
 *
 * All Rights Reserved. This work is distributed under the j2js Software License [1]
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * [1] http://www.j2js.com/license.txt
 */
public final class Double extends Number implements Comparable
{
	public static final double POSITIVE_INFINITY= 1.0 / 0.0;

	/**
	 * A constant holding the negative infinity of type
	 * double. It is equal to the value returned by
	 * Double.longBitsToDouble(0xfff0000000000000L).
	 */
	public static final double NEGATIVE_INFINITY= -1.0 / 0.0;

	// 2^512, 2^-512
	private static final double POWER_512= 1.3407807929942597E154;
	private static final double POWER_MINUS_512= 7.458340731200207E-155;
	// 2^256, 2^-256
	private static final double POWER_256= 1.157920892373162E77;
	private static final double POWER_MINUS_256= 8.636168555094445E-78;
	// 2^128, 2^-128
	private static final double POWER_128= 3.4028236692093846E38;
	private static final double POWER_MINUS_128= 2.9387358770557188E-39;
	// 2^64, 2^-64
	private static final double POWER_64= 18446744073709551616.0;
	private static final double POWER_MINUS_64= 5.421010862427522E-20;
	// 2^52, 2^-52
	private static final double POWER_52= 4503599627370496.0;
	private static final double POWER_MINUS_52= 2.220446049250313E-16;
	// 2^32, 2^-32
	private static final double POWER_32= 4294967296.0;
	private static final double POWER_MINUS_32= 2.3283064365386963E-10;
	// 2^31
	private static final double POWER_31= 2147483648.0;
	// 2^20, 2^-20
	private static final double POWER_20= 1048576.0;
	private static final double POWER_MINUS_20= 9.5367431640625E-7;
	// 2^16, 2^-16
	private static final double POWER_16= 65536.0;
	private static final double POWER_MINUS_16= 0.0000152587890625;
	// 2^8, 2^-8
	private static final double POWER_8= 256.0;
	private static final double POWER_MINUS_8= 0.00390625;
	// 2^4, 2^-4
	private static final double POWER_4= 16.0;
	private static final double POWER_MINUS_4= 0.0625;
	// 2^2, 2^-2
	private static final double POWER_2= 4.0;
	private static final double POWER_MINUS_2= 0.25;
	// 2^1, 2^-1
	private static final double POWER_1= 2.0;
	private static final double POWER_MINUS_1= 0.5;
	// 2^-1022 (smallest double non-denorm)
	private static final double POWER_MINUS_1022= 2.2250738585072014E-308;

	private static final double[] powers= { POWER_512, POWER_256, POWER_128, POWER_64, POWER_32, POWER_16, POWER_8, POWER_4, POWER_2, POWER_1 };

	private static final double[] invPowers= { POWER_MINUS_512, POWER_MINUS_256, POWER_MINUS_128, POWER_MINUS_64, POWER_MINUS_32, POWER_MINUS_16, POWER_MINUS_8, POWER_MINUS_4, POWER_MINUS_2, POWER_MINUS_1 };

	public static final double NaN= 0d / 0d;

	public static final Class TYPE= Class.getType("double");

	private double value;

	/**
	 * Constructs a newly allocated Double object that represents the primitive double argument.
	 */
	public Double(double d)
	{
		value= d;
	}

	/**
	 * Constructs a newly allocated Double object that represents the floating-point value of type double represented by the string.    * @param s
	 */
	public Double(String s)
	{
		value= parseDouble(s);
	}

	/**
	 * Compares this object to the specified object.
	 */
	public boolean equals(Object obj)
	{
		if (obj == null || !(obj instanceof Double))
			return false;
		return ((Double) obj).value == value;
	}

	/**
	 * Compares the two specified double values.
	 */
	public int compareTo(Double o)
	{
		if (!(o instanceof Double))
			throw new ClassCastException();
		Double d= (Double) o;
		if (isNaN() || d.isNaN())
		{
			if (isNaN() && d.isNaN())
				return 0;
			if (isNaN())
				return 1;
			return -1;
		}
		return Utils.cmp(value, d.doubleValue(), 0);
	}

	public double doubleValue()
	{
		return value;
	}

	public float floatValue()
	{
		return (float) value;
	}

	public int intValue()
	{
		return (int) value;
	}

	public long longValue()
	{
		return (long) value;
	}

	/**
	 * Returns true if this Double value is a Not-a-Number (NaN), false otherwise.
	 */
	public boolean isNaN()
	{
		return isNaN(value);
	}

	/**
	 * Returns true if the specified number is a Not-a-Number (NaN) value, false otherwise.
	 */
	public static boolean isNaN(double v)
	{
		ScriptHelper.put("value", v, null);
		return ScriptHelper.evalBoolean("isNaN(value)", null);
	}

	/**
	 * Returns a new double initialized to the value represented by the specified String, as performed by the valueOf method of class Double.
	 */
	public static double parseDouble(String s) throws NumberFormatException
	{
		if (s == null)
			throw new NullPointerException();
		s= s.trim();
		if (s.matches("(\\+|\\-)?NaN"))
			return NaN;

		if (!s.matches("(\\+|\\-)?\\d+(\\.\\d+)?"))
			throw new NumberFormatException("Invalid double: " + s);

		ScriptHelper.put("s", s, null);
		double d= ScriptHelper.evalDouble("parseFloat(s)", null);
		if (isNaN(d))
		{
			throw new NumberFormatException("Not a parsable double: " + s);
		}
		return d;
	}

	/**
	 * Returns an Double object holding the specified value. Calls to this
	 * method may be generated by the autoboxing feature.
	 */
	public static Double valueOf(double value)
	{
		return new Double(value);
	}

	/**
	 * Returns a Double object holding the double value represented by the argument string s.
	 */
	public static Double valueOf(String s) throws NumberFormatException
	{
		return new Double(parseDouble(s));
	}

	/**
	 * Returns a string representation of this Double object.
	 */
	public String toString()
	{
		ScriptHelper.put("value", value, this);
		return (String) ScriptHelper.eval("String(value)", this);
	}

	//    public static long doubleToLongBits(double value)
	//    {
	//	long result= doubleToRawLongBits(value);
	//	// Check for NaN based on values of bit fields, maximum
	//	// exponent and nonzero significand.
	//	if (((result & DoubleConsts.EXP_BIT_MASK) == DoubleConsts.EXP_BIT_MASK) && (result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
	//	    result= 0x7ff8000000000000L;
	//	return result;
	//    }

	public static double longBitsToDouble(long bits)
	{
		long ihi= (long) (bits >> 32);
		long ilo= (long) (bits & 0xffffffffL);
		if (ihi < 0)
		{
			ihi+= 0x100000000L;
		}
		if (ilo < 0)
		{
			ilo+= 0x100000000L;
		}

		boolean negative= (ihi & 0x80000000) != 0;
		int exp= (int) ((ihi >> 20) & 0x7ff);
		ihi&= 0xfffff; // remove sign bit and exponent

		if (exp == 0x0)
		{
			double d= (ihi * POWER_MINUS_20) + (ilo * POWER_MINUS_52);
			d*= POWER_MINUS_1022;
			return negative ? (d == 0.0 ? -0.0 : -d) : d;
		}
		else if (exp == 0x7ff)
		{
			if (ihi == 0 && ilo == 0)
			{
				return negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
			}
			else
			{
				return Double.NaN;
			}
		}

		// Normalize exponent
		exp-= 1023;

		double d= 1.0 + (ihi * POWER_MINUS_20) + (ilo * POWER_MINUS_52);
		if (exp > 0)
		{
			int bit= 512;
			for (int i= 0; i < 10; i++, bit>>= 1)
			{
				if (exp >= bit)
				{
					d*= powers[i];
					exp-= bit;
				}
			}
		}
		else if (exp < 0)
		{
			while (exp < 0)
			{
				int bit= 512;
				for (int i= 0; i < 10; i++, bit>>= 1)
				{
					if (exp <= -bit)
					{
						d*= invPowers[i];
						exp+= bit;
					}
				}
			}
		}
		return negative ? -d : d;
	}

	//    public static double longBitsToDouble(long bits)
	//    {
	//	System.out.println("longBitsToDouble:"+bits);
	//	return 0.0;
	////	throw new NotImplementedMethod("Double.longBitsToDouble");
	//    }

	public static long doubleToLongBits(final double v)
	{
		if (Double.isNaN(v))
		{
			// IEEE754, NaN exponent bits all 1s, and mantissa is	non-zero
			return 0x0FFFl << 51;
		}

		long sign= (v < 0 ? 0x1l << 63 : 0);
		long exponent= 0;

		double absV= Math.abs(v);
		// IEEE754 infinite numbers, exponent all 1s, mantissa is 0
		if (Double.isInfinite(v))
		{
			exponent= 0x07FFl << 52;
		}
		else
		{
			if (absV == 0.0)
			{
				// IEEE754, exponent is 0, mantissa is zero
				// we don't handle negative zero at the moment, it istreated as
				// positive zero
				exponent= 0l;
			}
			else
			{
				// get an approximation to the exponent
				int guess= (int) Math.floor(Math.log(absV) / Math.log(2));
				// force it to -1023, 1023 interval (<= -1023 =	denorm/zero)
				guess= Math.max(-1023, Math.min(guess, 1023));

				// divide away exponent guess
				double exp= Math.pow(2, guess);
				absV= absV / exp;

				// while the number is still bigger than a normalized	number
				// increment exponent guess
				while (absV > 2.0)
				{
					guess++;
					absV/= 2.0;
				}
				// if the number is smaller than a normalized number
				// decrement exponent
				while (absV < 1 && guess > 1024)
				{
					guess--;
					absV*= 2;
				}
				exponent= (guess + 1023l) << 52;
			}
		}
		// if denorm
		if (exponent <= 0)
		{
			absV/= 2;
		}

		// the input value has now been stripped of its exponent
		// and is in the range [0,2), we strip off the leading	decimal
		// and use the remainer as a percentage of the significand	value (2^52)
		long mantissa= (long) ((absV % 1) * Math.pow(2, 52));
		return sign | exponent | (mantissa & 0xfffffffffffffl);
	}

	static public boolean isInfinite(double v)
	{
		return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
	}

	public static String toString(double d)
	{
		return d + "";
	}

	public static int compare(double d1, double d2)
	{
		if (d1 < d2)
			return -1; // Neither val is NaN, thisVal is smaller
		if (d1 > d2)
			return 1; // Neither val is NaN, thisVal is larger

		// Cannot use doubleToRawLongBits because of possibility of NaNs.
		long thisBits= Double.doubleToLongBits(d1);
		long anotherBits= Double.doubleToLongBits(d2);

		return (thisBits == anotherBits ? 0 : // Values are equal
		        (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
		                1)); // (0.0, -0.0) or (NaN, !NaN)
	}
	
	public static int hashCode(double value)
	{
		return hashCode((long)value);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy