Code source Java lecture de la classe java.lang.Math

Code source Java lecture de la classe java.lang.Math

Objectif

«J'ai reçu une offre d'emploi en tant qu'ingénieur, mais j'en ai assez de ce que je devrais étudier pendant l'année avant de rejoindre l'entreprise. J'écrivais en Ruby, mais après avoir rejoint l'entreprise, je ne semble pas utiliser Ruby. .. .. → Familiarisez-vous avec Java. C'est aussi beaucoup d'étudier les modèles de conception.

Aperçu

Déclaration de classe

public final class Math {

Ne peut pas être hérité avec le modificateur final

constructeur

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

Ne peut pas être instancié

constant

    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;

Fonction trigonométrique

Comme mentionné dans le commentaire d'ouverture, la méthode du même nom dans la classe StrictMath est détournée.

    @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
    }

Et la mystérieuse annotation @ HotSpotIntrinsicCandidate. Hotspot Intrinsic? Intrinsic? Candidate? Je ne sais pas ce que cela signifie.

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

???

Que fait cette annotation?

Fonction --atan2: Il semble que lorsque vous entrez les coordonnées, il vous indiquera le bronzage du triangle rectangle qui le compose.

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

Différences entre les significations de la fonction atan et de la fonction atan2 \ -Mathématiques apprises avec des exemples concrets

Multipliez simplement par une constante

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

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

Colonne: double type

--Le type double est un nombre à virgule flottante 64 bits avec le code 1, la partie exposante 11 et la partie formelle 52 --Valeur représentée par double = (-1) Partie de code x 2 Partie exposant-1023 x 1. Partie formelle --2.225074 10-308 <valeur absolue du double <1.7797693 10 + 308

Référence: Type de virgule flottante et erreur

Exponentiel

    @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
    }

Après tout cours de mathématiques strictes

racine

--Racine carrée --Racine cubique

    @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
    }

Je me suis demandé ce que le nom IEEE (I Triple E: American Institute of Electrical and Electronic Engineers) avait inventé, mais cela semble être une division.

Défini par ** IEEE 754 ** (Aitori Purui 754, IEEE Standard for Floating-Point Arithmetic: littéralement traduit par «standard d'arithmétique en virgule flottante») Il semble que ce soit le cas.

--Format de base: une collection de données à virgule flottante en binaire et décimal .. Un nombre fini (zéro signé et un nombre non normalisé Y compris E9% 9D% 9E% E6% AD% A3% E8% A6% 8F% E5% 8C% 96% E6% 95% B0)), [Infinite](https://ja.wikipedia.org/wiki/ % E7% 84% A1% E9% 99% 90), consistant en une valeur spéciale "non numérique" (NaN). Il existe 5 types de formats de base, 3 types au format binaire et 2 types au format décimal.

Citation: IEEE 754 \ -Wikipedia

Rond

--ceil: arrondit la virgule décimale

  	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: arrondi

Enfin, un code décent et lisible est arrivé ...!

   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. Conversion d'entiers: Convertissez l'argument float en int / Convertissez le double en long
  1. ET l'argument int avec l'infini positif, décale 23 vers la droite
  2. 22 + 127 = 149- (valeur après décalage obtenue en 2.)

??? Abandonnez ... Etudiez l'arithmétique des décalages et IEEE754 puis recommencez ...

Puissance

--pow: puissance

/     
		 * @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
    }

nombre aléatoire

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

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

La classe Random est instanciée en tant que classe interne.

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;
    }

méthode suivante

    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));
    }

Système exact

Il semble lancer une ArithmeticException quand il déborde

Correspond respectivement à int et 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; Cela semble être la valeur minimale. Est-ce l'inversion de signe de la valeur minimale, c'est-à-dire de la valeur maximale, c'est-à-dire du débordement? --Depuis le commentaire, cela correspond à un complément 2 et la même valeur lorsque le signe est inversé. --Dans toIntExact, s'il déborde lors de la conversion en int, une erreur

    /**
     * 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 est un entier 64 bits

Je ne suis pas sûr ... Cela dit que je fais quelque chose de technique cité dans un livre

Maximum inférieur ou égal au nombre de quotients (le plus grand entier du quotient est arrondi vers le bas)

    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;
    }

Demandez-vous un mod comme ça ...!

Pensons concrètement.

  1. Soit (x, y) = (11, 5). Naturellement 11% 5 est 1
  2. floorDiv (11,5) → Commerce 2
  3. 2 * 5 = 10
  4. 11 - 10 = 1

Oh.

Valeur absolue

   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;
    }

Valeur maximale Valeur minimale

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

Variables de membre qui sont apparues soudainement

    // 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);

--Il semble qu'il était garanti que ce n'était pas NaN

Je suis reconnaissant que les variables membres soient faciles à lire et apparaissent juste avant d'être utilisées, plutôt que d'être au-dessus de tout.

    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

--Japonais inconnu

-Il semble être une opération de ∘ (x × y + z)

   @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

--Unité du dernier chiffre [ULP, erreur relative et epsilon machine] qui semble représenter la valeur absolue de l'erreur d'arrondi [https://jp.xlsoft.com/documents/intel/cvf/vf-html/pg/pg22_02_01_01.htm)

    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);
    }

Signum

Jugez le signe

    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)));
    }

--Il semble renvoyer 0,0 si d est 0,0 ou non-nombre, 1,0 pour les nombres positifs et -1,0 pour les nombres négatifs sinon.

Fonction triangulaire Fonction bicurve

    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);
    }

somme des carrés

Trouvez le côté diagonal du théorème des trois carrés

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

Fonction exponentielle, fonction logarithmique

    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);
    }


Nouvelle classe de mathématiques Java: partie 2 des nombres à virgule flottante

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));
        }
    }

Les deux n'ont renvoyé que des nombres à virgule flottante très proches. A quoi cela sert?

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);
    }

Il semble que le premier argument soit scaleFactor + 1.

Glossaire

--trigonométrique: trigonométrique

--fonction trigonométrique: fonction trigonométrique

--instrictique: Intrinsèque

--Transducteur: Convertisseur

Ce que j'ai trouvé

--Appel presque la méthode de la classe java.lang.StrictMath → Vous devriez relire la classe StrictMath ―― Comme le calcul des équipes est beaucoup utilisé, la connaissance du calcul des équipes est nécessaire pour le comprendre.

Question

Recommended Posts

Code source Java lecture de la classe java.lang.Math
Techniques de lecture du code source Java dans Eclipse
Lors de la lecture du code source
Structure de base du code source Java
Technologie de lecture du code source (cheet sheet)
[CLI JAWS-UG] CodeBuild: # 1 Création de code source (Java)
[Java] Flux du code source à l'exécution
[Java] Héritage de classe
Exécuter du code Java de manière scriptée
CONSEILS relatifs au code Java
classe Scanner java
Classe Java HashMap
Exemple de code Java 02
Exemple de code Java 03
Classe anonyme Java
À propos de la classe Java
Exemple de code Java 01
Code de caractère Java
[java] Classe abstraite
[Java] Classe d'objets
Classe locale Java
À propos de la division de classe (Java)
À propos de la classe Java StringBuilder
déclenchement automatique d'activation du code source Java eclipse lors de la saisie
[Java] À propos de la classe Singleton
Commentaires dans la source Java
java (fichier source fractionné)
Évaluer la source Java à partir de Java
Examen de la classe interne Java
Champ de type de classe Java
Programmation Java (structure de classe)
À propos de la classe abstraite de Java
Lecture de code CRuby (2): rb_newobj_of
Comment inverser la compilation du fichier apk en code source Java avec MAC
[Java] Référence de classe de wrapper Integer
Sous-chaîne de mémo Java (classe standard)
Astuces Java - Modificateurs de classe StaticUtility
Exemple de code de signature électronique (JAVA)
Sous-chaîne de classe Java inflexible String
Collection d'exemples de code parallèle Java
Longueur du mémo Java (classe standard)
[Implémentation] Notes de classe de processus java
À propos des types de chargeur de classe Java
Lecture de code CRuby (1): PROBABLE / IMPROBABLE
Comment utiliser la classe Java
[Java] Comparateur de la classe Collection
Définition et instanciation de classe Java
refactoring d'odeur de code [classe paresseuse]
[Windows] Le code Java est déformé
Mémo d'apprentissage Java (classe abstraite)
Java avec Visual Studio Code
Écrire du code de type Java8 en Java8
Résumé de la classe Java Math
[Java] Qu'est-ce que l'héritage de classe?
J'ai essayé l'analyse du code source
Méthode de classe variable de classe Java
[Java] Conseils pour l'écriture de la source
[Notions de base Java] Qu'est-ce que la classe?