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

src.org.python.core.util.ExtraMath Maven / Gradle / Ivy

Go to download

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

There is a newer version: 2.7.4
Show newest version
// Copyright (c) Corporation for National Research Initiatives
package org.python.core.util;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * A static utility class with two additional math functions.
 */
public class ExtraMath {

    public static double EPSILON = Math.pow(2.0, -52.0);

    public static double CLOSE = EPSILON * 2.0;

    /**
     * Are v and w "close" to each other? Uses a scaled tolerance.
     */
    public static boolean close(double v, double w, double tol) {
        if (v == w) {
            return true;
        }
        double scaled = tol * (Math.abs(v) + Math.abs(w)) / 2.0;
        return Math.abs(w - v) < scaled;
    }

    public static boolean close(double v, double w) {
        return close(v, w, CLOSE);
    }

    /**
     * Returns floor(v) except when v is very close to the next number, when it returns ceil(v);
     */
    public static double closeFloor(double v) {
        double floor = Math.floor(v);
        return close(v, floor + 1.0) ? floor + 1.0 : floor;
    }

    /**
     * Round the argument x to n decimal places. (Rounding is half-up in Python 2.) The method uses
     * BigDecimal, to compute r(x*10n)*10-n, where r() round to
     * the nearest integer. It takes some short-cuts for extreme values.
     * 

* For sufficiently small x*10n, the rounding is to zero, and the return value * is a signed zero (same sign as x). Suppose x = a*2b, where the significand * we must have a<2. Sufficiently small means such that n log210 < * -(b+2). *

* For sufficiently large x*10n, the adjustment of rounding is too small to * affect the least significant bit. That is a*2b represents an amount greater * than one, and rounding no longer affects the value, and the return is x. Since the matissa * has 52 fractional bits, sufficiently large means such that n log210 > * 52-b. * * @param x to round * @param n decimal places * @return x rounded. */ public static double round(double x, int n) { if (Double.isNaN(x) || Double.isInfinite(x) || x == 0.0) { // nans, infinities and zeros round to themselves return x; } else { // (Slightly less than) n*log2(10). float nlog2_10 = 3.3219f * n; // x = a * 2^b and a<2. int b = Math.getExponent(x); if (nlog2_10 > 52 - b) { // When n*log2(10) > nmax, the lsb of abs(x) is >1, so x rounds to itself. return x; } else if (nlog2_10 < -(b + 2)) { // When n*log2(10) < -(b+2), abs(x)<0.5*10^n so x rounds to (signed) zero. return Math.copySign(0.0, x); } else { // We have to work it out properly. BigDecimal xx = new BigDecimal(x); BigDecimal rr = xx.setScale(n, RoundingMode.HALF_UP); return rr.doubleValue(); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy