Java-Quellcode zum Lesen der Klasse java.lang.Math

Java-Quellcode zum Lesen der Klasse java.lang.Math

Zweck

――Ich habe ein Stellenangebot als Ingenieur bekommen, aber ich habe es satt, was ich für ein Jahr studieren sollte, bevor ich in das Unternehmen eintrete. Früher habe ich in Ruby geschrieben, aber nach meinem Eintritt in die Firma scheine ich Ruby nicht mehr zu verwenden. .. .. → Machen Sie sich mit Java vertraut. Es ist auch sehr wichtig, Designmuster zu studieren.

Überblick

--Version ist Java 9 ――Suchen Sie als Richtlinie, wo Sie interessiert sind

Klassenerklärung

public final class Math {

Kann nicht mit dem endgültigen Modifikator vererbt werden

Konstrukteur

    /**
     * Don't let anyone instantiate this class.
     */
    private Math() {}

Kann nicht instanziiert werden

Konstante

    public static final double E = 2.7182818284590452354;

    public static final double PI = 3.14159265358979323846;

    private static final double DEGREES_TO_RADIANS = 0.017453292519943295;

    private static final double RADIANS_TO_DEGREES = 57.29577951308232;

Trigonometrische Funktion

Wie im Eröffnungskommentar erwähnt, wird die gleichnamige Methode in der StrictMath-Klasse umgeleitet.

    @HotSpotIntrinsicCandidate
    public static double sin(double a) {
        return StrictMath.sin(a); // default impl. delegates to StrictMath
    }

    @HotSpotIntrinsicCandidate
    public static double cos(double a) {
        return StrictMath.cos(a); // default impl. delegates to StrictMath
    }

    @HotSpotIntrinsicCandidate
    public static double tan(double a) {
        return StrictMath.tan(a); // default impl. delegates to StrictMath
    }

    public static double asin(double a) {
        return StrictMath.asin(a); // default impl. delegates to StrictMath
    }

    public static double acos(double a) {
        return StrictMath.acos(a); // default impl. delegates to StrictMath
    }

    public static double atan(double a) {
        return StrictMath.atan(a); // default impl. delegates to StrictMath
    }

Und die mysteriöse Anmerkung "@ HotSpotIntrinsicCandidate". Hotspot Intrinsic? Intrinsic? Candidate? Ich weiß nicht, was es bedeutet.

@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface HotSpotIntrinsicCandidate {
}

???

Was macht diese Anmerkung?

--atan2-Funktion: Wenn Sie die Koordinaten eingeben, wird Ihnen anscheinend die Bräune des rechtwinkligen Dreiecks angezeigt, aus dem sie besteht.

    @HotSpotIntrinsicCandidate
    public static double atan2(double y, double x) {
        return StrictMath.atan2(y, x); // default impl. delegates to StrictMath
    }

Unterschiede zwischen den Bedeutungen der atan-Funktion und der atan2-Funktion \ -Mathematik anhand konkreter Beispiele

--Radian ⇄ Π Konvertierung

Einfach mit einer Konstanten multiplizieren

    public static double toRadians(double angdeg) {
        return angdeg * DEGREES_TO_RADIANS;
    }

    public static double toDegrees(double angrad) {
        return angrad * RADIANS_TO_DEGREES;
    }

Spalte: Doppeltyp

--Doppeltyp ist eine 64-Bit-Gleitkommazahl mit Code 1, Exponententeil 11 und formalem Teil 52 --Wert dargestellt durch "double = (-1) Code Teil x 2 Exponent Teil-1023 x 1. Formaler Teil"

Referenz: Gleitkommatyp und Fehler

Exponentiell

    @HotSpotIntrinsicCandidate
    public static double exp(double a) {
        return StrictMath.exp(a); // default impl. delegates to StrictMath
    }

    @HotSpotIntrinsicCandidate
    public static double log(double a) {
        return StrictMath.log(a); // default impl. delegates to StrictMath
    }

    @HotSpotIntrinsicCandidate
    public static double log10(double a) {
        return StrictMath.log10(a); // default impl. delegates to StrictMath
    }

Immerhin Strict Math Klasse

Wurzel

--Quadratwurzel --Kubikwurzel

    @HotSpotIntrinsicCandidate
    public static double sqrt(double a) {
        return StrictMath.sqrt(a); // default impl. delegates to StrictMath
                                   // Note that hardware sqrt instructions
                                   // frequently can be directly used by JITs
                                   // and should be much faster than doing
                                   // Math.sqrt in software.
    }

    public static double cbrt(double a) {
        return StrictMath.cbrt(a);
    }
    public static double IEEEremainder(double f1, double f2) {
        return StrictMath.IEEEremainder(f1, f2); // delegate to StrictMath
    }

Ich habe mich gefragt, wie der Name IEEE (I Triple E: Amerikanisches Institut für Elektro- und Elektronikingenieure) gekommen ist, aber es scheint eine Spaltung zu sein.

Definiert durch ** IEEE 754 ** (Aitori Purui 754, IEEE Standard für Gleitkomma-Arithmetik: wörtlich übersetzt als "Gleitkomma-Arithmetik-Standard") Es scheint so.

Zitat: IEEE 754 \ -Wikipedia

Runden

--ceil: Runden Sie den Dezimalpunkt auf --floor: Abrunden --rint: Auf den nächsten ganzzahligen Wert runden ← Wie unterscheidet es sich vom Runden?

  	public static double ceil(double a) {
        return StrictMath.ceil(a); // default impl. delegates to StrictMath
    }
		public static double floor(double a) {
        return StrictMath.floor(a); // default impl. delegates to StrictMath
    }

		public static double rint(double a) {
        return StrictMath.rint(a); // default impl. delegates to StrictMath
    }

--round: Rundung

Endlich ist ein anständiger und lesbarer Code eingetroffen ...!

   public static int round(float a) {
        int intBits = Float.floatToRawIntBits(a); //1 
        int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK)
                >> (FloatConsts.SIGNIFICAND_WIDTH - 1);// 2
        int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2
                + FloatConsts.EXP_BIAS) - biasedExp; //3
        if ((shift & -32) == 0) { // shift >= 0 && shift < 32
            // a is a finite number such that pow(2,-32) <= ulp(a) < 1
            int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK)
                    | (FloatConsts.SIGNIF_BIT_MASK + 1));
            if (intBits < 0) {
                r = -r;
            }
            // In the comments below each Java expression evaluates to the value
            // the corresponding mathematical expression:
            // (r) evaluates to a / ulp(a)
            // (r >> shift) evaluates to floor(a * 2)
            // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
            // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
            return ((r >> shift) + 1) >> 1;
        } else {
            // a is either
            // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2
            // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
            // - an infinity or NaN
            return (int) a;
        }
    }

    public static long round(double a) {
        long longBits = Double.doubleToRawLongBits(a);
        long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK)
                >> (DoubleConsts.SIGNIFICAND_WIDTH - 1);
        long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2
                + DoubleConsts.EXP_BIAS) - biasedExp;
        if ((shift & -64) == 0) { // shift >= 0 && shift < 64
            // a is a finite number such that pow(2,-64) <= ulp(a) < 1
            long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK)
                    | (DoubleConsts.SIGNIF_BIT_MASK + 1));
            if (longBits < 0) {
                r = -r;
            }
            // In the comments below each Java expression evaluates to the value
            // the corresponding mathematical expression:
            // (r) evaluates to a / ulp(a)
            // (r >> shift) evaluates to floor(a * 2)
            // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
            // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
            return ((r >> shift) + 1) >> 1;
        } else {
            // a is either
            // - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2
            // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
            // - an infinity or NaN
            return (long) a;
        }
    }


  1. Integer-Konvertierung: Konvertieren Sie das Argument float in int / Convert double in long ――Es wird gesagt, dass Sie die interne Bitdarstellung erhalten, nicht die Konvertierung (Cast).
  2. UND das Argument int mit positiver Unendlichkeit, 23 nach rechts verschieben
  3. 22 + 127 = 149- (Wert nach Verschiebung erhalten in 2.)

??? Aufgeben ... Shift Arithmetik und IEEE754 studieren und dann wieder von vorne beginnen ...

Leistung

--pow: Macht

/     
		 * @param   a   the base.
     * @param   b   the exponent.
     * @return  the value {@code a}<sup>{@code b}</sup>.
     */
@HotSpotIntrinsicCandidate
    public static double pow(double a, double b) {
        return StrictMath.pow(a, b); // default impl. delegates to StrictMath
    }

Zufallszahl

    private static final class RandomNumberGeneratorHolder {
        static final Random randomNumberGenerator = new Random();
    }

    public static double random() {
        return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
    }

Die Zufallsklasse wird als innere Klasse instanziiert.

Random.class

    private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)

		public double nextDouble() {
        return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
    }

nächste Methode

    protected int next(int bits) {
        long oldseed, nextseed;
        AtomicLong seed = this.seed;
        do {
            oldseed = seed.get();
            nextseed = (oldseed * multiplier + addend) & mask;
        } while (!seed.compareAndSet(oldseed, nextseed));
        return (int)(nextseed >>> (48 - bits));
    }

Genaues System

Es scheint eine ArithmeticException auszulösen, wenn sie überläuft

Entspricht int bzw. long

    @HotSpotIntrinsicCandidate
    public static int addExact(int x, int y) {
        int r = x + y;
        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
        if (((x ^ r) & (y ^ r)) < 0) {
            throw new ArithmeticException("integer overflow");
        }
        return r;
    }

    @HotSpotIntrinsicCandidate
    public static long addExact(long x, long y) {
        long r = x + y;
        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
        if (((x ^ r) & (y ^ r)) < 0) {
            throw new ArithmeticException("long overflow");
        }
        return r;
    }

    @HotSpotIntrinsicCandidate
    public static int subtractExact(int x, int y) {
        int r = x - y;
        // HD 2-12 Overflow iff the arguments have different signs and
        // the sign of the result is different from the sign of x
        if (((x ^ y) & (x ^ r)) < 0) {
            throw new ArithmeticException("integer overflow");
        }
        return r;
    }

    @HotSpotIntrinsicCandidate
    public static long subtractExact(long x, long y) {
        long r = x - y;
        // HD 2-12 Overflow iff the arguments have different signs and
        // the sign of the result is different from the sign of x
        if (((x ^ y) & (x ^ r)) < 0) {
            throw new ArithmeticException("long overflow");
        }
        return r;
    }

    @HotSpotIntrinsicCandidate
    public static int multiplyExact(int x, int y) {
        long r = (long)x * (long)y;
        if ((int)r != r) {
            throw new ArithmeticException("integer overflow");
        }
        return (int)r;
    }

    public static long multiplyExact(long x, int y) {
        return multiplyExact(x, (long)y);
    }

    @HotSpotIntrinsicCandidate
    public static long multiplyExact(long x, long y) {
        long r = x * y;
        long ax = Math.abs(x);
        long ay = Math.abs(y);
        if (((ax | ay) >>> 31 != 0)) {
            // Some bits greater than 2^31 that might cause overflow
            // Check the result using the divide operator
            // and check for the special case of Long.MIN_VALUE * -1
           if (((y != 0) && (r / y != x)) ||
               (x == Long.MIN_VALUE && y == -1)) {
                throw new ArithmeticException("long overflow");
            }
        }
        return r;
    }

    @HotSpotIntrinsicCandidate
    public static int incrementExact(int a) {
        if (a == Integer.MAX_VALUE) {
            throw new ArithmeticException("integer overflow");
        }

        return a + 1;
    }
    @HotSpotIntrinsicCandidate
    public static long incrementExact(long a) {
        if (a == Long.MAX_VALUE) {
            throw new ArithmeticException("long overflow");
        }

        return a + 1L;
    }

    @HotSpotIntrinsicCandidate
    public static int decrementExact(int a) {
        if (a == Integer.MIN_VALUE) {
            throw new ArithmeticException("integer overflow");
        }

        return a - 1;
    }

    @HotSpotIntrinsicCandidate
    public static long decrementExact(long a) {
        if (a == Long.MIN_VALUE) {
            throw new ArithmeticException("long overflow");
          //    @Native public static final long MIN_VALUE = 0x8000000000000000L;
        }

        return a - 1L;
    }
    @HotSpotIntrinsicCandidate
    public static int negateExact(int a) {
        if (a == Integer.MIN_VALUE) {
            throw new ArithmeticException("integer overflow");
        }

        return -a;
    }
    @HotSpotIntrinsicCandidate
    public static long negateExact(long a) {
        if (a == Long.MIN_VALUE) {
            throw new ArithmeticException("long overflow");
        }

        return -a;
    }
    public static int toIntExact(long value) {
        if ((int)value != value) {
            throw new ArithmeticException("integer overflow");
        }
        return (int)value;
    }

--long MIN_VALUE = 0x8000000000000000L; Dies scheint der Mindestwert zu sein. Ist es die Vorzeichenumkehrung des Minimalwerts, dh des Maximalwerts, dh des Überlaufs?

    /**
     * Returns as a {@code long} the most significant 64 bits of the 128-bit
     * product of two 64-bit factors.
     *
     * @param x the first value
     * @param y the second value
     * @return the result
     * @since 9
     */
public static long multiplyHigh(long x, long y) {
        if (x < 0 || y < 0) {
            // Use technique from section 8-2 of Henry S. Warren, Jr.,
            // Hacker's Delight (2nd ed.) (Addison Wesley, 2013), 173-174.
            long x1 = x >> 32;
            long x2 = x & 0xFFFFFFFFL;
            long y1 = y >> 32;
            long y2 = y & 0xFFFFFFFFL;
            long z2 = x2 * y2;
            long t = x1 * y2 + (z2 >>> 32);
            long z1 = t & 0xFFFFFFFFL;
            long z0 = t >> 32;
            z1 += x2 * y1;
            return x1 * y1 + z0 + (z1 >> 32);
        } else {
            // Use Karatsuba technique with two base 2^32 digits.
            long x1 = x >>> 32;
            long y1 = y >>> 32;
            long x2 = x & 0xFFFFFFFFL;
            long y2 = y & 0xFFFFFFFFL;
            long A = x1 * y1;
            long B = x2 * y2;
            long C = (x1 + x2) * (y1 + y2);
            long K = C - A - B;
            return (((B >>> 32) + K) >>> 32) + A;
        }
    }

--long type ist eine 64-Bit-Ganzzahl

Ich bin mir nicht sicher ... Es heißt, dass ich etwas Technisches mache, das aus einem Buch zitiert wird

Maximal kleiner oder gleich der Anzahl der Quotienten (die größte Ganzzahl im Quotienten wird abgerundet)

    public static int floorDiv(int x, int y) {
        int r = x / y;
        // if the signs are different and modulo not zero, round down
        if ((x ^ y) < 0 && (r * y != x)) {
            r--;
        }
        return r;
    }

    public static long floorDiv(long x, int y) {
        return floorDiv(x, (long)y);
    }

    public static long floorDiv(long x, long y) {
        long r = x / y;
        // if the signs are different and modulo not zero, round down
        if ((x ^ y) < 0 && (r * y != x)) {
            r--;
        }
        return r;
    }

Mod

   public static int floorMod(int x, int y) {
        return x - floorDiv(x, y) * y;
    }

    public static int floorMod(long x, int y) {
        // Result cannot overflow the range of int.
        return (int)(x - floorDiv(x, y) * y);
    }

    public static long floorMod(long x, long y) {
        return x - floorDiv(x, y) * y;
    }

Fragst du nach so einem Mod ...!

Denken wir konkret.

  1. Sei (x, y) = (11, 5). Natürlich ist 11% 5 1
  2. floorDiv (11,5) → Handel 2
  3. 2 * 5 = 10
  4. 11 - 10 = 1

Oh.

Absolutwert

   public static int abs(int a) {
        return (a < 0) ? -a : a;
    }

    public static long abs(long a) {
        return (a < 0) ? -a : a;
    }

    public static float abs(float a) {
        return (a <= 0.0F) ? 0.0F - a : a;
    }

    @HotSpotIntrinsicCandidate
    public static double abs(double a) {
        return (a <= 0.0D) ? 0.0D - a : a;
    }

    @HotSpotIntrinsicCandidate
    public static int max(int a, int b) {
        return (a >= b) ? a : b;
    }

Maximalwert Minimaler Wert

   public static long max(long a, long b) {
        return (a >= b) ? a : b;
    }

Mitgliedsvariablen, die plötzlich herauskamen

    // Use raw bit-wise conversions on guaranteed non-NaN arguments.
    private static long negativeZeroFloatBits  = Float.floatToRawIntBits(-0.0f);
    private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);

Ich bin dankbar, dass es leicht zu lesen ist, dass die Mitgliedsvariablen kurz vor der Verwendung erscheinen, anstatt über allem zu stehen.

    public static float max(float a, float b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0f) &&
            (b == 0.0f) &&
            (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a >= b) ? a : b;
    }

  public static double max(double a, double b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0d) &&
            (b == 0.0d) &&
            (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a >= b) ? a : b;  
  }

    @HotSpotIntrinsicCandidate
    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }

    public static long min(long a, long b) {
        return (a <= b) ? a : b;
    }

    public static float min(float a, float b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0f) &&
            (b == 0.0f) &&
            (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a <= b) ? a : b;
    }

    public static double min(double a, double b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0d) &&
            (b == 0.0d) &&
            (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a <= b) ? a : b;
    }

Fused Multiply Add

-Es scheint eine Operation von ∘ (x × y + z) zu sein.

   @HotSpotIntrinsicCandidate
    public static double fma(double a, double b, double c) {
        /*
         * Infinity and NaN arithmetic is not quite the same with two
         * roundings as opposed to just one so the simple expression
         * "a * b + c" cannot always be used to compute the correct
         * result.  With two roundings, the product can overflow and
         * if the addend is infinite, a spurious NaN can be produced
         * if the infinity from the overflow and the infinite addend
         * have opposite signs.
         */

        // First, screen for and handle non-finite input values whose
        // arithmetic is not supported by BigDecimal.
        if (Double.isNaN(a) || Double.isNaN(b) || Double.isNaN(c)) {
            return Double.NaN;
        } else { // All inputs non-NaN
            boolean infiniteA = Double.isInfinite(a);
            boolean infiniteB = Double.isInfinite(b);
            boolean infiniteC = Double.isInfinite(c);
            double result;

            if (infiniteA || infiniteB || infiniteC) {
                if (infiniteA && b == 0.0 ||
                    infiniteB && a == 0.0 ) {
                    return Double.NaN;
                }
                // Store product in a double field to cause an
                // overflow even if non-strictfp evaluation is being
                // used.
                double product = a * b;
                if (Double.isInfinite(product) && !infiniteA && !infiniteB) {
                    // Intermediate overflow; might cause a
                    // spurious NaN if added to infinite c.
                    assert Double.isInfinite(c);
                    return c;
                } else {
                    result = product + c;
                    assert !Double.isFinite(result);
                    return result;
                }
            } else { // All inputs finite
                BigDecimal product = (new BigDecimal(a)).multiply(new BigDecimal(b));
                if (c == 0.0) { // Positive or negative zero
                    // If the product is an exact zero, use a
                    // floating-point expression to compute the sign
                    // of the zero final result. The product is an
                    // exact zero if and only if at least one of a and
                    // b is zero.
                    if (a == 0.0 || b == 0.0) {
                        return a * b + c;
                    } else {
                        // The sign of a zero addend doesn't matter if
                        // the product is nonzero. The sign of a zero
                        // addend is not factored in the result if the
                        // exact product is nonzero but underflows to
                        // zero; see IEEE-754 2008 section 6.3 "The
                        // sign bit".
                        return product.doubleValue();
                    }
                } else {
                    return product.add(new BigDecimal(c)).doubleValue();
                }
            }
        }
    }
  @HotSpotIntrinsicCandidate
    public static float fma(float a, float b, float c) {
        /*
         *  Since the double format has more than twice the precision
         *  of the float format, the multiply of a * b is exact in
         *  double. The add of c to the product then incurs one
         *  rounding error. Since the double format moreover has more
         *  than (2p + 2) precision bits compared to the p bits of the
         *  float format, the two roundings of (a * b + c), first to
         *  the double format and then secondarily to the float format,
         *  are equivalent to rounding the intermediate result directly
         *  to the float format.
         *
         * In terms of strictfp vs default-fp concerns related to
         * overflow and underflow, since
         *
         * (Float.MAX_VALUE * Float.MAX_VALUE) << Double.MAX_VALUE
         * (Float.MIN_VALUE * Float.MIN_VALUE) >> Double.MIN_VALUE
         *
         * neither the multiply nor add will overflow or underflow in
         * double. Therefore, it is not necessary for this method to
         * be declared strictfp to have reproducible
         * behavior. However, it is necessary to explicitly store down
         * to a float variable to avoid returning a value in the float
         * extended value set.
         */
        float result = (float)(((double) a * (double) b ) + (double) c);
        return result;
    }

Unit in the Last Place

    public static double ulp(double d) {
        int exp = getExponent(d);

        switch(exp) {
        case Double.MAX_EXPONENT + 1:       // NaN or infinity
            return Math.abs(d);

        case Double.MIN_EXPONENT - 1:       // zero or subnormal
            return Double.MIN_VALUE;

        default:
            assert exp <= Double.MAX_EXPONENT && exp >= Double.MIN_EXPONENT;

            // ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
            exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH-1);
            if (exp >= Double.MIN_EXPONENT) {
                return powerOfTwoD(exp);
            }
            else {
                // return a subnormal result; left shift integer
                // representation of Double.MIN_VALUE appropriate
                // number of positions
                return Double.longBitsToDouble(1L <<
                (exp - (Double.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1)) ));
            }
        }
    }

   public static float ulp(float f) {
        int exp = getExponent(f);

        switch(exp) {
        case Float.MAX_EXPONENT+1:        // NaN or infinity
            return Math.abs(f);

        case Float.MIN_EXPONENT-1:        // zero or subnormal
            return Float.MIN_VALUE;

        default:
            assert exp <= Float.MAX_EXPONENT && exp >= Float.MIN_EXPONENT;

            // ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
            exp = exp - (FloatConsts.SIGNIFICAND_WIDTH-1);
            if (exp >= Float.MIN_EXPONENT) {
                return powerOfTwoF(exp);
            } else {
                // return a subnormal result; left shift integer
                // representation of FloatConsts.MIN_VALUE appropriate
                // number of positions
                return Float.intBitsToFloat(1 <<
                (exp - (Float.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1)) ));
            }
        }
    }
    public static double signum(double d) {
        return (d == 0.0 || Double.isNaN(d))?d:copySign(1.0, d);
    }

--subnormale Nummer: [Nicht normalisierte Nummer \ -Wikipedia](https://ja.wikipedia.org/wiki/%E9%9D%9E%E6%AD%A3%E8%A6%8F%E5%8C%96 % E6% 95% B0) Eine Zahl sehr nahe an 0

Signum

Beurteile das Zeichen

    public static double signum(double d) {
        return (d == 0.0 || Double.isNaN(d))?d:copySign(1.0, d);
    }
    public static float signum(float f) {
        return (f == 0.0f || Float.isNaN(f))?f:copySign(1.0f, f);
    }

...
  
    public static double copySign(double magnitude, double sign) {
        return Double.longBitsToDouble((Double.doubleToRawLongBits(sign) &
                                        (DoubleConsts.SIGN_BIT_MASK)) |
                                       (Double.doubleToRawLongBits(magnitude) &
                                        (DoubleConsts.EXP_BIT_MASK |
                                         DoubleConsts.SIGNIF_BIT_MASK)));
    }

    public static float copySign(float magnitude, float sign) {
        return Float.intBitsToFloat((Float.floatToRawIntBits(sign) &
                                     (FloatConsts.SIGN_BIT_MASK)) |
                                    (Float.floatToRawIntBits(magnitude) &
                                     (FloatConsts.EXP_BIT_MASK |
                                      FloatConsts.SIGNIF_BIT_MASK)));
    }

Dreiecksfunktion Bikurvenfunktion

    public static double sinh(double x) {
        return StrictMath.sinh(x);
    }
    public static double cosh(double x) {
        return StrictMath.cosh(x);
    }
    public static double tanh(double x) {
        return StrictMath.tanh(x);
    }

Quadratsumme

Finden Sie die diagonale Seite des Drei-Quadrat-Theorems

    public static double hypot(double x, double y) {
        return StrictMath.hypot(x, y);
    }

Exponentialfunktion, logarithmische Funktion

    public static double expm1(double x) {
        return StrictMath.expm1(x);
    }
    public static double log1p(double x) {
        return StrictMath.log1p(x);
    }
    public static int getExponent(float f) {
        /*
         * Bitwise convert f to integer, mask out exponent bits, shift
         * to the right and then subtract out float's bias adjust to
         * get true exponent value
         */
        return ((Float.floatToRawIntBits(f) & FloatConsts.EXP_BIT_MASK) >>
                (FloatConsts.SIGNIFICAND_WIDTH - 1)) - FloatConsts.EXP_BIAS;
    }

    public static int getExponent(double d) {
        /*
         * Bitwise convert d to long, mask out exponent bits, shift
         * to the right and then subtract out double's bias adjust to
         * get true exponent value.
         */
        return (int)(((Double.doubleToRawLongBits(d) & DoubleConsts.EXP_BIT_MASK) >>
                      (DoubleConsts.SIGNIFICAND_WIDTH - 1)) - DoubleConsts.EXP_BIAS);
    }


Neue Java-Mathematikklasse: Teil 2 Gleitkommazahlen

nextAfter, nextUp,

    public static double nextAfter(double start, double direction) {
       

        // Branch to descending case first as it is more costly than ascending
        // case due to start != 0.0d conditional.
        if (start > direction) { // descending
            if (start != 0.0d) {
                final long transducer = Double.doubleToRawLongBits(start);
                return Double.longBitsToDouble(transducer + ((transducer > 0L) ? -1L : 1L));
            } else { // start == 0.0d && direction < 0.0d
                return -Double.MIN_VALUE;
            }
        } else if (start < direction) { // ascending
            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
            // then bitwise convert start to integer.
            final long transducer = Double.doubleToRawLongBits(start + 0.0d);
            return Double.longBitsToDouble(transducer + ((transducer >= 0L) ? 1L : -1L));
        } else if (start == direction) {
            return direction;
        } else { // isNaN(start) || isNaN(direction)
            return start + direction;
        }
    }

    public static float nextAfter(float start, double direction) {
  
        if (start > direction) { // descending
            if (start != 0.0f) {
                final int transducer = Float.floatToRawIntBits(start);
                return Float.intBitsToFloat(transducer + ((transducer > 0) ? -1 : 1));
            } else { // start == 0.0f && direction < 0.0f
                return -Float.MIN_VALUE;
            }
        } else if (start < direction) { // ascending
            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
            // then bitwise convert start to integer.
            final int transducer = Float.floatToRawIntBits(start + 0.0f);
            return Float.intBitsToFloat(transducer + ((transducer >= 0) ? 1 : -1));
        } else if (start == direction) {
            return (float)direction;
        } else { // isNaN(start) || isNaN(direction)
            return start + (float)direction;
        }
    }

    public static double nextUp(double d) {
        // Use a single conditional and handle the likely cases first.
        if (d < Double.POSITIVE_INFINITY) {
            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0).
            final long transducer = Double.doubleToRawLongBits(d + 0.0D);
            return Double.longBitsToDouble(transducer + ((transducer >= 0L) ? 1L : -1L));
        } else { // d is NaN or +Infinity
            return d;
        }
    }

    public static float nextUp(float f) {
        // Use a single conditional and handle the likely cases first.
        if (f < Float.POSITIVE_INFINITY) {
            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0).
            final int transducer = Float.floatToRawIntBits(f + 0.0F);
            return Float.intBitsToFloat(transducer + ((transducer >= 0) ? 1 : -1));
        } else { // f is NaN or +Infinity
            return f;
        }
    }

    public static double nextDown(double d) {
        if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY)
            return d;
        else {
            if (d == 0.0)
                return -Double.MIN_VALUE;
            else
                return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
                                               ((d > 0.0d)?-1L:+1L));
        }
    }

    public static float nextDown(float f) {
        if (Float.isNaN(f) || f == Float.NEGATIVE_INFINITY)
            return f;
        else {
            if (f == 0.0f)
                return -Float.MIN_VALUE;
            else
                return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
                                            ((f > 0.0f)?-1:+1));
        }
    }

Es wurde nur festgestellt, dass beide sehr nahe Gleitkommazahlen zurückgeben. Was wird es verwendet?

scalb

   public static double scalb(double d, int scaleFactor) {
   
        final int MAX_SCALE = Double.MAX_EXPONENT + -Double.MIN_EXPONENT +
                              DoubleConsts.SIGNIFICAND_WIDTH + 1;
        int exp_adjust = 0;
        int scale_increment = 0;
        double exp_delta = Double.NaN;

        // Make sure scaling factor is in a reasonable range

        if(scaleFactor < 0) {
            scaleFactor = Math.max(scaleFactor, -MAX_SCALE);
            scale_increment = -512;
            exp_delta = twoToTheDoubleScaleDown;
        }
        else {
            scaleFactor = Math.min(scaleFactor, MAX_SCALE);
            scale_increment = 512;
            exp_delta = twoToTheDoubleScaleUp;
        }

        // Calculate (scaleFactor % +/-512), 512 = 2^9, using
        // technique from "Hacker's Delight" section 10-2.
        int t = (scaleFactor >> 9-1) >>> 32 - 9;
        exp_adjust = ((scaleFactor + t) & (512 -1)) - t;

        d *= powerOfTwoD(exp_adjust);
        scaleFactor -= exp_adjust;

        while(scaleFactor != 0) {
            d *= exp_delta;
            scaleFactor -= scale_increment;
        }
        return d;
    }
    public static float scalb(float f, int scaleFactor) {
        final int MAX_SCALE = Float.MAX_EXPONENT + -Float.MIN_EXPONENT +
                              FloatConsts.SIGNIFICAND_WIDTH + 1;

        // Make sure scaling factor is in a reasonable range
        scaleFactor = Math.max(Math.min(scaleFactor, MAX_SCALE), -MAX_SCALE);
      return (float)((double)f*powerOfTwoD(scaleFactor));
    }


    // Constants used in scalb
    static double twoToTheDoubleScaleUp = powerOfTwoD(512);
    static double twoToTheDoubleScaleDown = powerOfTwoD(-512);

    static double powerOfTwoD(int n) {
        assert(n >= Double.MIN_EXPONENT && n <= Double.MAX_EXPONENT);
        return Double.longBitsToDouble((((long)n + (long)DoubleConsts.EXP_BIAS) <<
                                        (DoubleConsts.SIGNIFICAND_WIDTH-1))
                                       & DoubleConsts.EXP_BIT_MASK);
    }


  	static float powerOfTwoF(int n) {
        assert(n >= Float.MIN_EXPONENT && n <= Float.MAX_EXPONENT);
        return Float.intBitsToFloat(((n + FloatConsts.EXP_BIAS) <<
                                     (FloatConsts.SIGNIFICAND_WIDTH-1))
                                    & FloatConsts.EXP_BIT_MASK);
    }

Es scheint, dass das erste Argument scaleFactor + 1 ist.

Glossar

--trigonometrisch: Trigonometrisch

--trigonometrische Funktion: Trigonometrische Funktion

--instrictic: Intrinsic

Was ich fand

Frage

--Was macht die Annotation "@ target"? --Dinge, die eher auf Anmerkungen als auf Kommentare abzielen. --Retention RUNTIME ist diejenige, bei der die Informationen bei Verwendung der Klasse in der JVM wiedergegeben werden (verbleiben).

Recommended Posts

Java-Quellcode zum Lesen der Klasse java.lang.Math
Techniken zum Lesen von Java-Quellcode in Eclipse
Beim Lesen des Quellcodes
Grundstruktur des Java-Quellcodes
Technologie zum Lesen des Quellcodes (Cheet Sheet)
[JAWS-UG CLI] CodeBuild: # 1 Erstellen von Quellcode (Java)
[Java] Fluss vom Quellcode zur Ausführung
[Java] Klassenvererbung
Führen Sie Java-Code skriptweise aus
Java-Code-TIPPS
Java-Scanner-Klasse
Java HashMap-Klasse
Java-Beispielcode 02
Java-Beispielcode 03
Anonyme Java-Klasse
Über die Java-Klasse
Java-Beispielcode 01
Java-Zeichencode
[Java] Abstrakte Klasse
[Java] Objektklasse
Lokale Java-Klasse
Über die Klassenteilung (Java)
Informationen zur Java StringBuilder-Klasse
Die automatische Aktivierung des Eclipse-Java-Quellcodes wird bei der Eingabe ausgelöst
[Java] Über Singleton Class
Kommentare in der Java-Quelle
Java (geteilte Quelldatei)
Eval Java-Quelle von Java
Überprüfung der Java-Innenklasse
Feld für den Java-Klassentyp
Java-Programmierung (Klassenstruktur)
Über die abstrakte Klasse von Java
CRuby Code Reading (2): rb_newobj_of
So kehren Sie die Kompilierung der Apk-Datei in Java-Quellcode mit MAC um
[Java] Integer-Wrapper-Klassenreferenz
Java-Memo-Teilzeichenfolge (Standardklasse)
Java-Tipps - Modifikatoren der StataticUtility-Klasse
Beispielcode für elektronische Signatur (JAVA)
Java unflexibler String-Klassen-Teilstring
Java Parallel Code Sample Collection
Länge des Java-Memos (Standardklasse)
[Implementierung] Java Prozessklassennotizen
Informationen zu Java Class Loader-Typen
CRuby Code Reading (1): LIKELY / UNLIKELY
Verwendung der Java-Klasse
[Java] Komparator der Collection-Klasse
Definition und Instanziierung von Java-Klassen
Code Geruch Refactoring [faule Klasse]
[Windows] Java-Code ist verstümmelt
Java-Lernnotiz (abstrakte Klasse)
Java mit Visual Studio Code
Schreiben Sie Java8-ähnlichen Code in Java8
Zusammenfassung der Java Math Klasse
[Java] Was ist Klassenvererbung?
Ich habe versucht, den Quellcode zu analysieren
Java-Klasse Variable Klassenmethode
[Java] Tipps zum Schreiben der Quelle
[Java-Grundlagen] Was ist Klasse?