예제 #1
0
 /**
  * Returns the largest power of 10 that is less than or equal to the
  * the specified positive value.
  *
  * @param d the <code>double</code> number.
  * @return <code>floor(Log10(abs(d)))</code>
  * @throws ArithmeticException if <code>d &lt;= 0<code> or <code>d</code>
  *         is <code>NaN</code> or <code>Infinity</code>.
  **/
 public static int floorLog10(double d) {
   int guess = (int) (LOG2_DIV_LOG10 * MathLib.floorLog2(d));
   double pow10 = MathLib.toDoublePow10(1, guess);
   if ((pow10 <= d) && (pow10 * 10 > d)) return guess;
   if (pow10 > d) return guess - 1;
   return guess + 1;
 }
예제 #2
0
  private CGAffineTransform nodeToParentTransform() {
    if (isTransformDirty_) {
      transform_.setToIdentity();

      if (!isRelativeAnchorPoint_ && !CGPoint.equalToPoint(anchorPointInPixels_, zero)) {
        transform_.translate(anchorPointInPixels_.x, anchorPointInPixels_.y);
      }

      if (!CGPoint.equalToPoint(position_, zero)) transform_.translate(position_.x, position_.y);

      if (rotation_ != 0) transform_.rotate(-ccMacros.CC_DEGREES_TO_RADIANS(rotation_));

      if (skewX_ != 0 || skewY_ != 0) {
        /** create a skewed coordinate system and apply the skew to the transform */
        transform_ =
            transform_.getTransformConcat(
                CGAffineTransform.make(
                    1.0f,
                    MathLib.tan(ccMacros.CC_DEGREES_TO_RADIANS(skewY_)),
                    MathLib.tan(ccMacros.CC_DEGREES_TO_RADIANS(skewX_)),
                    1.0f,
                    0.0f,
                    0.0f));
      }

      if (!(scaleX_ == 1 && scaleY_ == 1)) transform_.scale(scaleX_, scaleY_);

      if (!CGPoint.equalToPoint(anchorPointInPixels_, zero))
        transform_.translate(-anchorPointInPixels_.x, -anchorPointInPixels_.y);

      isTransformDirty_ = false;
    }

    return transform_;
  }
예제 #3
0
 /**
  * Returns the angle theta such that <code>(x == cos(theta)) && (y == sin(theta))</code>.
  *
  * @param y the y value.
  * @param x the x value.
  * @return the angle theta in radians.
  */
 public static double atan2(double y, double x) {
   final double epsilon = 1E-128;
   if (MathLib.abs(x) > epsilon) {
     double temp = MathLib.atan(MathLib.abs(y) / MathLib.abs(x));
     if (x < 0.0) temp = PI - temp;
     if (y < 0.0) temp = TWO_PI - temp;
     return temp;
   } else if (y > epsilon) return HALF_PI;
   else if (y < -epsilon) return 3 * HALF_PI;
   else return 0.0;
 }
예제 #4
0
 /**
  * Returns a pseudo random <code>long</code> value in the range <code>[min, max]</code> (fast and
  * thread-safe without synchronization).
  *
  * @param min the minimum value inclusive.
  * @param max the maximum value inclusive.
  * @return a pseudo random number in the range <code>[min, max]</code>.
  */
 public static long random(long min, long max) {
   long next = RANDOM.nextLong();
   if ((next >= min) && (next <= max)) return next;
   next += Long.MIN_VALUE;
   if ((next >= min) && (next <= max)) return next;
   // We should not have interval overflow as the interval has to be less
   // or equal to Long.MAX_VALUE (otherwise we would have exited before).
   final long interval = 1L + max - min; // Positive.
   if (interval <= 0) throw new Error("Interval error"); // Sanity check.
   return MathLib.abs(next % interval) + min;
 }
예제 #5
0
 /**
  * Returns a pseudo random <code>int</code> value in the range <code>[min, max]</code> (fast and
  * thread-safe without synchronization).
  *
  * @param min the minimum value inclusive.
  * @param max the maximum value exclusive.
  * @return a pseudo random number in the range <code>[min, max]</code>.
  */
 public static int random(int min, int max) {
   int next = RANDOM.nextInt();
   if ((next >= min) && (next <= max)) return next;
   next += Integer.MIN_VALUE;
   if ((next >= min) && (next <= max)) return next;
   // We should not have interval overflow as the interval has to be less
   // or equal to Integer.MAX_VALUE (otherwise we would have exited before).
   final int interval = 1 + max - min; // Positive.
   if (interval <= 0) throw new Error("Interval [" + min + ".." + max + "] error"); // In case.
   return MathLib.abs(next % interval) + min;
 }
예제 #6
0
  static double _atan(double x) {
    double w, s1, s2, z;
    int ix, hx, id;
    long xBits = Double.doubleToLongBits(x);
    int __HIx = (int) (xBits >> 32);
    int __LOx = (int) xBits;

    hx = __HIx;
    ix = hx & 0x7fffffff;
    if (ix >= 0x44100000) { // if |x| >= 2^66
      if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (__LOx != 0))) return x + x; // NaN
      if (hx > 0) return atanhi[3] + atanlo[3];
      else return -atanhi[3] - atanlo[3];
    }
    if (ix < 0x3fdc0000) { // |x| < 0.4375
      if (ix < 0x3e200000) // |x| < 2^-29
      if (huge + x > one) return x;
      id = -1;
    } else {
      x = MathLib.abs(x);
      if (ix < 0x3ff30000) // |x| < 1.1875
      if (ix < 0x3fe60000) { // 7/16 <=|x|<11/16
          id = 0;
          x = (2.0 * x - one) / (2.0 + x);
        } else { // 11/16<=|x|< 19/16
          id = 1;
          x = (x - one) / (x + one);
        }
      else if (ix < 0x40038000) { // |x| < 2.4375
        id = 2;
        x = (x - 1.5) / (one + 1.5 * x);
      } else { // 2.4375 <= |x| < 2^66
        id = 3;
        x = -1.0 / x;
      }
    }
    // end of argument reduction
    z = x * x;
    w = z * z;
    // break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly
    s1 = z * (aT[0] + w * (aT[2] + w * (aT[4] + w * (aT[6] + w * (aT[8] + w * aT[10])))));
    s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9]))));
    if (id < 0) return x - x * (s1 + s2);
    else {
      z = atanhi[id] - ((x * (s1 + s2) - atanlo[id]) - x);
      return (hx < 0) ? -z : z;
    }
  }
예제 #7
0
 /**
  * Returns the closest <code>double</code> representation of the specified <code>long</code>
  * number multiplied by a power of two.
  *
  * @param m the <code>long</code> multiplier.
  * @param n the power of two exponent.
  * @return <code>m * 2<sup>n</sup></code>.
  */
 public static double toDoublePow2(long m, int n) {
   if (m == 0) return 0.0;
   if (m == Long.MIN_VALUE) return toDoublePow2(Long.MIN_VALUE >> 1, n + 1);
   if (m < 0) return -toDoublePow2(-m, n);
   int bitLength = MathLib.bitLength(m);
   int shift = bitLength - 53;
   long exp = 1023L + 52 + n + shift; // Use long to avoid overflow.
   if (exp >= 0x7FF) return Double.POSITIVE_INFINITY;
   if (exp <= 0) { // Degenerated number (subnormal, assume 0 for bit 52)
     if (exp <= -54) return 0.0;
     return toDoublePow2(m, n + 54) / 18014398509481984L; // 2^54 Exact.
   }
   // Normal number.
   long bits =
       (shift > 0)
           ? (m >> shift) + ((m >> (shift - 1)) & 1)
           : // Rounding.
           m << -shift;
   if (((bits >> 52) != 1) && (++exp >= 0x7FF)) return Double.POSITIVE_INFINITY;
   bits &= 0x000fffffffffffffL; // Clears MSB (bit 52)
   bits |= exp << 52;
   return Double.longBitsToDouble(bits);
 }
예제 #8
0
 /**
  * Returns the hyperbolic tangent of x.
  *
  * @param x the value for which the hyperbolic tangent is calculated.
  * @return <code>(exp(2 * x) - 1) / (exp(2 * x) + 1)</code>
  */
 public static double tanh(double x) {
   return (MathLib.exp(2 * x) - 1) / (MathLib.exp(2 * x) + 1);
 }
예제 #9
0
 /**
  * Returns the hyperbolic cosine of x.
  *
  * @param x the value for which the hyperbolic cosine is calculated.
  * @return <code>(exp(x) + exp(-x)) / 2</code>
  */
 public static double cosh(double x) {
   return (MathLib.exp(x) + MathLib.exp(-x)) * 0.5;
 }
예제 #10
0
 /**
  * Returns the hyperbolic sine of x.
  *
  * @param x the value for which the hyperbolic sine is calculated.
  * @return <code>(exp(x) - exp(-x)) / 2</code>
  */
 public static double sinh(double x) {
   return (MathLib.exp(x) - MathLib.exp(-x)) * 0.5;
 }
예제 #11
0
 /**
  * Returns the arc tangent of the specified value, in the range of -<i>pi</i>/2 through
  * <i>pi</i>/2.
  *
  * @param x the value whose arc tangent is to be returned.
  * @return the arc tangent in radians for the specified value.
  * @see <a href="http://mathworld.wolfram.com/InverseTangent.html">Inverse Tangent -- from
  *     MathWorld</a>
  */
 public static double atan(double x) {
   return MathLib._atan(x);
 }
예제 #12
0
 /**
  * Returns the arc cosine of the specified value, in the range of 0.0 through <i>pi</i>.
  *
  * @param x the value whose arc cosine is to be returned.
  * @return the arc cosine in radians for the specified value.
  */
 public static double acos(double x) {
   return HALF_PI - MathLib.asin(x);
 }
예제 #13
0
 /**
  * Returns the remainder of the division of the specified two arguments.
  *
  * @param x the dividend.
  * @param y the divisor.
  * @return <code>x - round(x / y) * y</code>
  */
 public static double rem(double x, double y) {
   double tmp = x / y;
   if (MathLib.abs(tmp) <= Long.MAX_VALUE) return x - MathLib.round(tmp) * y;
   else return NaN;
 }
예제 #14
0
  /**
   * Returns the closest <code>long</code> representation of the specified <code>double</code>
   * number multiplied by a power of ten.
   *
   * @param d the <code>double</code> multiplier.
   * @param n the power of two exponent.
   * @return <code>d * 10<sup>n</sup></code>.
   */
  public static long toLongPow10(double d, int n) {
    long bits = Double.doubleToLongBits(d);
    boolean isNegative = (bits >> 63) != 0;
    int exp = ((int) (bits >> 52)) & 0x7FF;
    long m = bits & 0x000fffffffffffffL;
    if (exp == 0x7FF) throw new ArithmeticException("Cannot convert to long (Infinity or NaN)");
    if (exp == 0) {
      if (m == 0) return 0L;
      return toLongPow10(d * 1E16, n - 16);
    }
    m |= 0x0010000000000000L; // Sets MSB (bit 52)
    int pow2 = exp - 1023 - 52;
    // Retrieves 63 bits m with n == 0.
    if (n >= 0) {
      // Works with 4 x 32 bits registers (x3:x2:x1:x0)
      long x0 = 0; // 32 bits.
      long x1 = 0; // 32 bits.
      long x2 = m & MASK_32; // 32 bits.
      long x3 = m >>> 32; // 32 bits.
      while (n != 0) {
        int i = (n >= POW5_INT.length) ? POW5_INT.length - 1 : n;
        int coef = POW5_INT[i]; // 31 bits max.

        if (((int) x0) != 0) x0 *= coef; // 63 bits max.
        if (((int) x1) != 0) x1 *= coef; // 63 bits max.
        x2 *= coef; // 63 bits max.
        x3 *= coef; // 63 bits max.

        x1 += x0 >>> 32;
        x0 &= MASK_32;

        x2 += x1 >>> 32;
        x1 &= MASK_32;

        x3 += x2 >>> 32;
        x2 &= MASK_32;

        // Adjusts powers.
        pow2 += i;
        n -= i;

        // Normalizes (x3 should be 32 bits max).
        long carry = x3 >>> 32;
        if (carry != 0) { // Shift.
          x0 = x1;
          x1 = x2;
          x2 = x3 & MASK_32;
          x3 = carry;
          pow2 += 32;
        }
      }

      // Merges registers to a 63 bits mantissa.
      int shift = 31 - MathLib.bitLength(x3); // -1..30
      pow2 -= shift;
      m =
          (shift < 0)
              ? (x3 << 31) | (x2 >>> 1)
              : // x3 is 32 bits.
              (((x3 << 32) | x2) << shift) | (x1 >>> (32 - shift));

    } else { // n < 0

      // Works with x1:x0 126 bits register.
      long x1 = m; // 63 bits.
      long x0 = 0; // 63 bits.
      while (true) {

        // Normalizes x1:x0
        int shift = 63 - MathLib.bitLength(x1);
        x1 <<= shift;
        x1 |= x0 >>> (63 - shift);
        x0 = (x0 << shift) & MASK_63;
        pow2 -= shift;

        // Checks if division has to be performed.
        if (n == 0) break; // Done.

        // Retrieves power of 5 divisor.
        int i = (-n >= POW5_INT.length) ? POW5_INT.length - 1 : -n;
        int divisor = POW5_INT[i];

        // Performs the division (126 bits by 31 bits).
        long wh = (x1 >>> 32);
        long qh = wh / divisor;
        long r = wh - qh * divisor;
        long wl = (r << 32) | (x1 & MASK_32);
        long ql = wl / divisor;
        r = wl - ql * divisor;
        x1 = (qh << 32) | ql;

        wh = (r << 31) | (x0 >>> 32);
        qh = wh / divisor;
        r = wh - qh * divisor;
        wl = (r << 32) | (x0 & MASK_32);
        ql = wl / divisor;
        x0 = (qh << 32) | ql;

        // Adjusts powers.
        n += i;
        pow2 -= i;
      }
      m = x1;
    }
    if (pow2 > 0) throw new ArithmeticException("Overflow");
    if (pow2 < -63) return 0;
    m = (m >> -pow2) + ((m >> -(pow2 + 1)) & 1); // Rounding.
    return isNegative ? -m : m;
  }
예제 #15
0
  /**
   * Returns the closest <code>double</code> representation of the specified <code>long</code>
   * number multiplied by a power of ten.
   *
   * @param m the <code>long</code> multiplier.
   * @param n the power of ten exponent.
   * @return <code>multiplier * 10<sup>n</sup></code>.
   */
  public static double toDoublePow10(long m, int n) {
    if (m == 0) return 0.0;
    if (m == Long.MIN_VALUE) return toDoublePow10(Long.MIN_VALUE / 10, n + 1);
    if (m < 0) return -toDoublePow10(-m, n);
    if (n >= 0) { // Positive power.
      if (n > 308) return Double.POSITIVE_INFINITY;
      // Works with 4 x 32 bits registers (x3:x2:x1:x0)
      long x0 = 0; // 32 bits.
      long x1 = 0; // 32 bits.
      long x2 = m & MASK_32; // 32 bits.
      long x3 = m >>> 32; // 32 bits.
      int pow2 = 0;
      while (n != 0) {
        int i = (n >= POW5_INT.length) ? POW5_INT.length - 1 : n;
        int coef = POW5_INT[i]; // 31 bits max.

        if (((int) x0) != 0) x0 *= coef; // 63 bits max.
        if (((int) x1) != 0) x1 *= coef; // 63 bits max.
        x2 *= coef; // 63 bits max.
        x3 *= coef; // 63 bits max.

        x1 += x0 >>> 32;
        x0 &= MASK_32;

        x2 += x1 >>> 32;
        x1 &= MASK_32;

        x3 += x2 >>> 32;
        x2 &= MASK_32;

        // Adjusts powers.
        pow2 += i;
        n -= i;

        // Normalizes (x3 should be 32 bits max).
        long carry = x3 >>> 32;
        if (carry != 0) { // Shift.
          x0 = x1;
          x1 = x2;
          x2 = x3 & MASK_32;
          x3 = carry;
          pow2 += 32;
        }
      }

      // Merges registers to a 63 bits mantissa.
      int shift = 31 - MathLib.bitLength(x3); // -1..30
      pow2 -= shift;
      long mantissa =
          (shift < 0)
              ? (x3 << 31) | (x2 >>> 1)
              : // x3 is 32 bits.
              (((x3 << 32) | x2) << shift) | (x1 >>> (32 - shift));
      return toDoublePow2(mantissa, pow2);

    } else { // n < 0
      if (n < -324 - 20) return 0.0;

      // Works with x1:x0 126 bits register.
      long x1 = m; // 63 bits.
      long x0 = 0; // 63 bits.
      int pow2 = 0;
      while (true) {

        // Normalizes x1:x0
        int shift = 63 - MathLib.bitLength(x1);
        x1 <<= shift;
        x1 |= x0 >>> (63 - shift);
        x0 = (x0 << shift) & MASK_63;
        pow2 -= shift;

        // Checks if division has to be performed.
        if (n == 0) break; // Done.

        // Retrieves power of 5 divisor.
        int i = (-n >= POW5_INT.length) ? POW5_INT.length - 1 : -n;
        int divisor = POW5_INT[i];

        // Performs the division (126 bits by 31 bits).
        long wh = (x1 >>> 32);
        long qh = wh / divisor;
        long r = wh - qh * divisor;
        long wl = (r << 32) | (x1 & MASK_32);
        long ql = wl / divisor;
        r = wl - ql * divisor;
        x1 = (qh << 32) | ql;

        wh = (r << 31) | (x0 >>> 32);
        qh = wh / divisor;
        r = wh - qh * divisor;
        wl = (r << 32) | (x0 & MASK_32);
        ql = wl / divisor;
        x0 = (qh << 32) | ql;

        // Adjusts powers.
        n += i;
        pow2 -= i;
      }
      return toDoublePow2(x1, pow2);
    }
  }
예제 #16
0
 /**
  * Returns <i>{@link #E e}</i> raised to the specified power.
  *
  * @param x the exponent.
  * @return <code><i>e</i><sup>x</sup></code>
  * @see <a href="http://mathworld.wolfram.com/ExponentialFunction.html">Exponential Function --
  *     from MathWorld</a>
  */
 public static double exp(double x) {
   return MathLib._ieee754_exp(x);
 }
예제 #17
0
 /**
  * Returns the natural logarithm (base <i>{@link #E e}</i>) of the specified value.
  *
  * @param x the value greater than <code>0.0</code>.
  * @return the value y such as <code><i>e</i><sup>y</sup> == x</code>
  */
 public static double log(double x) {
   return MathLib._ieee754_log(x);
 }
예제 #18
0
 /**
  * Returns the arc sine of the specified value, in the range of -<i>pi</i>/2 through <i>pi</i>/2.
  *
  * @param x the value whose arc sine is to be returned.
  * @return the arc sine in radians for the specified value.
  */
 public static double asin(double x) {
   if (x < -1.0 || x > 1.0) return MathLib.NaN;
   if (x == -1.0) return -HALF_PI;
   if (x == 1.0) return HALF_PI;
   return MathLib.atan(x / MathLib.sqrt(1.0 - x * x));
 }