001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.math4.core.jdkmath;
018
019import java.util.function.IntUnaryOperator;
020import java.util.function.IntBinaryOperator;
021import java.util.function.LongUnaryOperator;
022import java.util.function.LongBinaryOperator;
023import java.util.function.DoubleUnaryOperator;
024import java.util.function.DoubleBinaryOperator;
025import java.util.function.DoubleToLongFunction;
026import java.util.function.DoubleToIntFunction;
027import java.util.function.LongToIntFunction;
028import java.util.function.DoubleSupplier;
029
030/**
031 * Wrapper for alternative implementations of {@link Math} functions.
032 * For example, a call to {@code Math.sin(x)} can be replaced by a call
033 * to {@code JdkMath.sin(x)}.
034 *
035 * <p>
036 * This class is a "drop-in" replacement for both Math and StrictMath,
037 * up to the <em>minimal</em> JDK version required by this library
038 * (meaning that, although the library can be used on <em>more</em>
039 * recent JVMs, the {@code JdkMath} class may be missing the methods
040 * that were absent in older JDKs).
041 *
042 * <p>
043 * Based on the value, at class initialization, of the system property
044 * {@code org.apache.commons.math.jdkmath}, this class redirects to a
045 * specific implementation:
046 * <ul>
047 *  <li>{@code CM}: {@link AccurateMath}</li>
048 *  <li>{@code JDK}: {@link Math}</li>
049 * </ul>
050 * When the property is undefined, {@code CM} is the default value.
051 */
052public final class JdkMath {
053    /** Constant. */
054    public static final double PI;
055    /** Constant. */
056    public static final double E;
057    /** Property identifier.. */
058    private static final String PROPERTY_KEY = "org.apache.commons.math.jdkmath";
059    /** abs(x). */
060    private static final IntUnaryOperator ABS_INT;
061    /** abs(x). */
062    private static final LongUnaryOperator ABS_LONG;
063    /** abs(x). */
064    private static final FloatUnaryOperator ABS_FLOAT;
065    /** abs(x). */
066    private static final DoubleUnaryOperator ABS_DOUBLE;
067    /** acos(x). */
068    private static final DoubleUnaryOperator ACOS;
069    /** acosh(x). */
070    private static final DoubleUnaryOperator ACOSH;
071    /** addExact(x, y). */
072    private static final IntBinaryOperator ADDEXACT_INT;
073    /** addExact(x, y). */
074    private static final LongBinaryOperator ADDEXACT_LONG;
075    /** asin(x). */
076    private static final DoubleUnaryOperator ASIN;
077    /** asinh(x). */
078    private static final DoubleUnaryOperator ASINH;
079    /** atan(x). */
080    private static final DoubleUnaryOperator ATAN;
081    /** atan2(x, y). */
082    private static final DoubleBinaryOperator ATAN2;
083    /** atanh(x). */
084    private static final DoubleUnaryOperator ATANH;
085    /** cbrt(x). */
086    private static final DoubleUnaryOperator CBRT;
087    /** ceil(x). */
088    private static final DoubleUnaryOperator CEIL;
089    /** copySign(x, y). */
090    private static final FloatBinaryOperator COPYSIGN_FLOAT;
091    /** copySign(x, y). */
092    private static final DoubleBinaryOperator COPYSIGN_DOUBLE;
093    /** cos(x). */
094    private static final DoubleUnaryOperator COS;
095    /** cosh(x). */
096    private static final DoubleUnaryOperator COSH;
097    /** decrementExact(x). */
098    private static final IntUnaryOperator DECREMENTEXACT_INT;
099    /** decrementExact(x). */
100    private static final LongUnaryOperator DECREMENTEXACT_LONG;
101    /** exp(x). */
102    private static final DoubleUnaryOperator EXP;
103    /** expm1(x). */
104    private static final DoubleUnaryOperator EXPM1;
105    /** floor(x). */
106    private static final DoubleUnaryOperator FLOOR;
107    /** floorDiv(x, y). */
108    private static final IntBinaryOperator FLOORDIV_INT;
109    /** floorDiv(x, y). */
110    private static final LongBinaryOperator FLOORDIV_LONG;
111    /** floorMod(x, y). */
112    private static final IntBinaryOperator FLOORMOD_INT;
113    /** floorMod(x, y). */
114    private static final LongBinaryOperator FLOORMOD_LONG;
115    /** getExponent(x). */
116    private static final FloatToIntFunction GETEXPONENT_FLOAT;
117    /** getExponent(x). */
118    private static final DoubleToIntFunction GETEXPONENT_DOUBLE;
119    /** hypot(x, y). */
120    private static final DoubleBinaryOperator HYPOT;
121    /** IEEEremainder(x, y). */
122    private static final DoubleBinaryOperator IEEEREMAINDER;
123    /** incrementExact(x). */
124    private static final IntUnaryOperator INCREMENTEXACT_INT;
125    /** incrementExact(x). */
126    private static final LongUnaryOperator INCREMENTEXACT_LONG;
127    /** log(x). */
128    private static final DoubleUnaryOperator LOG;
129    /** log10(x). */
130    private static final DoubleUnaryOperator LOG10;
131    /** log1p(x). */
132    private static final DoubleUnaryOperator LOG1P;
133    /** max(x, y). */
134    private static final IntBinaryOperator MAX_INT;
135    /** max(x, y). */
136    private static final LongBinaryOperator MAX_LONG;
137    /** max(x, y). */
138    private static final FloatBinaryOperator MAX_FLOAT;
139    /** max(x, y). */
140    private static final DoubleBinaryOperator MAX_DOUBLE;
141    /** min(x, y). */
142    private static final IntBinaryOperator MIN_INT;
143    /** min(x, y). */
144    private static final LongBinaryOperator MIN_LONG;
145    /** min(x, y). */
146    private static final FloatBinaryOperator MIN_FLOAT;
147    /** min(x, y). */
148    private static final DoubleBinaryOperator MIN_DOUBLE;
149    /** multiplyExact(x, y). */
150    private static final IntBinaryOperator MULTIPLYEXACT_INT;
151    /** multiplyExact(x, y). */
152    private static final LongBinaryOperator MULTIPLYEXACT_LONG;
153    /** negateExact(x). */
154    private static final IntUnaryOperator NEGATEEXACT_INT;
155    /** negateExact(x). */
156    private static final LongUnaryOperator NEGATEEXACT_LONG;
157    /** nextAfter(x, y). */
158    private static final FloatDouble2FloatOperator NEXTAFTER_FLOAT;
159    /** nextAfter(x, y). */
160    private static final DoubleBinaryOperator NEXTAFTER_DOUBLE;
161    /** nextDown(x). */
162    private static final FloatUnaryOperator NEXTDOWN_FLOAT;
163    /** nextDown(x). */
164    private static final DoubleUnaryOperator NEXTDOWN_DOUBLE;
165    /** nextUp(x). */
166    private static final FloatUnaryOperator NEXTUP_FLOAT;
167    /** nextUp(x). */
168    private static final DoubleUnaryOperator NEXTUP_DOUBLE;
169    /** pow(x, y). */
170    private static final DoubleBinaryOperator POW;
171    /** random(). */
172    private static final DoubleSupplier RANDOM;
173    /** rint(x). */
174    private static final DoubleUnaryOperator RINT;
175    /** round(x). */
176    private static final DoubleToLongFunction ROUND_DOUBLE;
177    /** round(x). */
178    private static final FloatToIntFunction ROUND_FLOAT;
179    /** scalb(x, y). */
180    private static final DoubleInt2DoubleOperator SCALB_DOUBLE;
181    /** scalb(x, y). */
182    private static final FloatInt2FloatOperator SCALB_FLOAT;
183    /** signum(x). */
184    private static final FloatUnaryOperator SIGNUM_FLOAT;
185    /** signum(x). */
186    private static final DoubleUnaryOperator SIGNUM_DOUBLE;
187    /** sin(x). */
188    private static final DoubleUnaryOperator SIN;
189    /** sinh(x). */
190    private static final DoubleUnaryOperator SINH;
191    /** sqrt(x). */
192    private static final DoubleUnaryOperator SQRT;
193    /** subtractExact(x, y). */
194    private static final IntBinaryOperator SUBTRACTEXACT_INT;
195    /** subtractExact(x, y). */
196    private static final LongBinaryOperator SUBTRACTEXACT_LONG;
197    /** tan(x). */
198    private static final DoubleUnaryOperator TAN;
199    /** tanh(x). */
200    private static final DoubleUnaryOperator TANH;
201    /** toDegrees(x). */
202    private static final DoubleUnaryOperator TODEGREES;
203    /** toIntExact(x). */
204    private static final LongToIntFunction TOINTEXACT;
205    /** toRadians(x). */
206    private static final DoubleUnaryOperator TORADIANS;
207    /** ulp(x). */
208    private static final DoubleUnaryOperator ULP_DOUBLE;
209    /** ulp(x). */
210    private static final FloatUnaryOperator ULP_FLOAT;
211
212    /** Available implementations of {@link Math} functions. */
213    public enum Impl {
214        /** {@link AccurateMath Commons Math}. */
215        CM,
216        /** {@link Math JDK}. */
217        JDK
218    }
219
220    static {
221        final String prop = System.getProperty(PROPERTY_KEY);
222        final Impl impl = prop != null ?
223            Impl.valueOf(prop) :
224            Impl.CM;
225
226
227        switch (impl) {
228        case CM:
229            PI = AccurateMath.PI;
230            E = AccurateMath.E;
231            ABS_INT = AccurateMath::abs;
232            ABS_LONG = AccurateMath::abs;
233            ABS_FLOAT = AccurateMath::abs;
234            ABS_DOUBLE = AccurateMath::abs;
235            ACOS = AccurateMath::acos;
236            ACOSH = AccurateMath::acosh;
237            ADDEXACT_INT = AccurateMath::addExact;
238            ADDEXACT_LONG = AccurateMath::addExact;
239            ASIN = AccurateMath::asin;
240            ASINH = AccurateMath::asinh;
241            ATAN = AccurateMath::atan;
242            ATAN2 = AccurateMath::atan2;
243            ATANH = AccurateMath::atanh;
244            CBRT = AccurateMath::cbrt;
245            CEIL = AccurateMath::ceil;
246            COPYSIGN_FLOAT = AccurateMath::copySign;
247            COPYSIGN_DOUBLE = AccurateMath::copySign;
248            COS = AccurateMath::cos;
249            COSH = AccurateMath::cosh;
250            DECREMENTEXACT_INT = AccurateMath::decrementExact;
251            DECREMENTEXACT_LONG = AccurateMath::decrementExact;
252            EXP = AccurateMath::exp;
253            EXPM1 = AccurateMath::expm1;
254            FLOOR = AccurateMath::floor;
255            FLOORDIV_INT = AccurateMath::floorDiv;
256            FLOORDIV_LONG = AccurateMath::floorDiv;
257            FLOORMOD_INT = AccurateMath::floorMod;
258            FLOORMOD_LONG = AccurateMath::floorMod;
259            GETEXPONENT_FLOAT = AccurateMath::getExponent;
260            GETEXPONENT_DOUBLE = AccurateMath::getExponent;
261            HYPOT = AccurateMath::hypot;
262            IEEEREMAINDER = AccurateMath::IEEEremainder;
263            INCREMENTEXACT_INT = AccurateMath::incrementExact;
264            INCREMENTEXACT_LONG = AccurateMath::incrementExact;
265            LOG = AccurateMath::log;
266            LOG10 = AccurateMath::log10;
267            LOG1P = AccurateMath::log1p;
268            MAX_INT = AccurateMath::max;
269            MAX_LONG = AccurateMath::max;
270            MAX_FLOAT = AccurateMath::max;
271            MAX_DOUBLE = AccurateMath::max;
272            MIN_INT = AccurateMath::min;
273            MIN_LONG = AccurateMath::min;
274            MIN_FLOAT = AccurateMath::min;
275            MIN_DOUBLE = AccurateMath::min;
276            MULTIPLYEXACT_INT = AccurateMath::multiplyExact;
277            MULTIPLYEXACT_LONG = AccurateMath::multiplyExact;
278            NEGATEEXACT_INT = Math::negateExact; // Not implemented.
279            NEGATEEXACT_LONG = Math::negateExact; // Not implemented.
280            NEXTAFTER_FLOAT = AccurateMath::nextAfter;
281            NEXTAFTER_DOUBLE = AccurateMath::nextAfter;
282            NEXTDOWN_FLOAT = AccurateMath::nextDown;
283            NEXTDOWN_DOUBLE = AccurateMath::nextDown;
284            NEXTUP_FLOAT = AccurateMath::nextUp;
285            NEXTUP_DOUBLE = AccurateMath::nextUp;
286            POW = AccurateMath::pow;
287            RANDOM = Math::random; // Not implemented.
288            RINT = AccurateMath::rint;
289            ROUND_DOUBLE = AccurateMath::round;
290            ROUND_FLOAT = AccurateMath::round;
291            SCALB_DOUBLE = AccurateMath::scalb;
292            SCALB_FLOAT = AccurateMath::scalb;
293            SIGNUM_DOUBLE = AccurateMath::signum;
294            SIGNUM_FLOAT = AccurateMath::signum;
295            SQRT = Math::sqrt; // Not implemented.
296            SIN = AccurateMath::sin;
297            SINH = AccurateMath::sinh;
298            SUBTRACTEXACT_INT = AccurateMath::subtractExact;
299            SUBTRACTEXACT_LONG = AccurateMath::subtractExact;
300            TAN = AccurateMath::tan;
301            TANH = AccurateMath::tanh;
302            TODEGREES = AccurateMath::toDegrees;
303            TOINTEXACT = AccurateMath::toIntExact;
304            TORADIANS = AccurateMath::toRadians;
305            ULP_DOUBLE = AccurateMath::ulp;
306            ULP_FLOAT = AccurateMath::ulp;
307            break;
308
309        case JDK:
310            PI = Math.PI;
311            E = Math.E;
312            ABS_INT = Math::abs;
313            ABS_LONG = Math::abs;
314            ABS_FLOAT = Math::abs;
315            ABS_DOUBLE = Math::abs;
316            ACOS = Math::acos;
317            ACOSH = AccurateMath::acosh; // Not implemented.
318            ADDEXACT_INT = Math::addExact;
319            ADDEXACT_LONG = Math::addExact;
320            ASIN = Math::asin;
321            ASINH = AccurateMath::asinh; // Not implemented.
322            ATAN = Math::atan;
323            ATAN2 = Math::atan2;
324            ATANH = AccurateMath::atanh; // Not implemented.
325            CBRT = Math::cbrt;
326            CEIL = Math::ceil;
327            COPYSIGN_FLOAT = Math::copySign;
328            COPYSIGN_DOUBLE = Math::copySign;
329            COS = Math::cos;
330            COSH = Math::cosh;
331            DECREMENTEXACT_INT = Math::decrementExact;
332            DECREMENTEXACT_LONG = Math::decrementExact;
333            EXP = Math::exp;
334            EXPM1 = Math::expm1;
335            FLOOR = Math::floor;
336            FLOORDIV_INT = Math::floorDiv;
337            FLOORDIV_LONG = Math::floorDiv;
338            FLOORMOD_INT = Math::floorMod;
339            FLOORMOD_LONG = Math::floorMod;
340            GETEXPONENT_FLOAT = Math::getExponent;
341            GETEXPONENT_DOUBLE = Math::getExponent;
342            HYPOT = Math::hypot;
343            IEEEREMAINDER = Math::IEEEremainder;
344            INCREMENTEXACT_INT = Math::incrementExact;
345            INCREMENTEXACT_LONG = Math::incrementExact;
346            LOG = Math::log;
347            LOG10 = Math::log10;
348            LOG1P = Math::log1p;
349            MAX_INT = Math::max;
350            MAX_LONG = Math::max;
351            MAX_FLOAT = Math::max;
352            MAX_DOUBLE = Math::max;
353            MIN_INT = Math::min;
354            MIN_LONG = Math::min;
355            MIN_FLOAT = Math::min;
356            MIN_DOUBLE = Math::min;
357            MULTIPLYEXACT_INT = Math::multiplyExact;
358            MULTIPLYEXACT_LONG = Math::multiplyExact;
359            NEGATEEXACT_INT = Math::negateExact;
360            NEGATEEXACT_LONG = Math::negateExact;
361            NEXTAFTER_FLOAT = Math::nextAfter;
362            NEXTAFTER_DOUBLE = Math::nextAfter;
363            NEXTDOWN_FLOAT = Math::nextDown;
364            NEXTDOWN_DOUBLE = Math::nextDown;
365            NEXTUP_FLOAT = Math::nextUp;
366            NEXTUP_DOUBLE = Math::nextUp;
367            POW = Math::pow;
368            RANDOM = Math::random;
369            RINT = Math::rint;
370            ROUND_DOUBLE = Math::round;
371            ROUND_FLOAT = Math::round;
372            SCALB_DOUBLE = Math::scalb;
373            SCALB_FLOAT = Math::scalb;
374            SIGNUM_DOUBLE = Math::signum;
375            SIGNUM_FLOAT = Math::signum;
376            SIN = Math::sin;
377            SINH = Math::sinh;
378            SQRT = Math::sqrt;
379            SUBTRACTEXACT_INT = Math::subtractExact;
380            SUBTRACTEXACT_LONG = Math::subtractExact;
381            TAN = Math::tan;
382            TANH = Math::tanh;
383            TODEGREES = Math::toDegrees;
384            TOINTEXACT = Math::toIntExact;
385            TORADIANS = Math::toRadians;
386            ULP_DOUBLE = Math::ulp;
387            ULP_FLOAT = Math::ulp;
388            break;
389
390        default:
391            throw new IllegalStateException("Internal error"); // Should never happen.
392        }
393    }
394
395    /** Utility class. */
396    private JdkMath() {}
397
398    /**
399     * @param x Number.
400     * @return abs(x).
401     *
402     * @see Math#abs(int)
403     */
404    public static int abs(int x) {
405        return ABS_INT.applyAsInt(x);
406    }
407
408    /**
409     * @param x Number.
410     * @return abs(x).
411     *
412     * @see Math#abs(long)
413     */
414    public static long abs(long x) {
415        return ABS_LONG.applyAsLong(x);
416    }
417
418    /**
419     * @param x Number.
420     * @return abs(x).
421     *
422     * @see Math#abs(float)
423     */
424    public static float abs(float x) {
425        return ABS_FLOAT.applyAsFloat(x);
426    }
427
428    /**
429     * @param x Number.
430     * @return abs(x).
431     *
432     * @see Math#abs(double)
433     */
434    public static double abs(double x) {
435        return ABS_DOUBLE.applyAsDouble(x);
436    }
437
438    /**
439     * @param x Number.
440     * @return acos(x).
441     *
442     * @see Math#acos(double)
443     */
444    public static double acos(double x) {
445        return ACOS.applyAsDouble(x);
446    }
447
448    /**
449     * @param x Number.
450     * @return acosh(x).
451     */
452    public static double acosh(double x) {
453        return ACOSH.applyAsDouble(x);
454    }
455
456    /**
457     * @param x Number.
458     * @param y Number.
459     * @return addExact(x, y).
460     *
461     * @see Math#addExact(int,int)
462     */
463    public static int addExact(int x,
464                               int y) {
465        return ADDEXACT_INT.applyAsInt(x, y);
466    }
467
468    /**
469     * @param x Number.
470     * @param y Number.
471     * @return addExact(x, y).
472     *
473     * @see Math#addExact(long,long)
474     */
475    public static long addExact(long x,
476                                long y) {
477        return ADDEXACT_LONG.applyAsLong(x, y);
478    }
479
480    /**
481     * @param x Number.
482     * @return asin(x).
483     *
484     * @see Math#asin(double)
485     */
486    public static double asin(double x) {
487        return ASIN.applyAsDouble(x);
488    }
489
490    /**
491     * @param x Number.
492     * @return asinh(x).
493     */
494    public static double asinh(double x) {
495        return ASINH.applyAsDouble(x);
496    }
497
498    /**
499     * @param x Number.
500     * @return atan(x).
501     *
502     * @see Math#atan(double)
503     */
504    public static double atan(double x) {
505        return ATAN.applyAsDouble(x);
506    }
507
508    /**
509     * @param y Number.
510     * @param x Number.
511     * @return atan2(y, x).
512     *
513     * @see Math#atan2(double,double)
514     */
515    public static double atan2(double y,
516                               double x) {
517        return ATAN2.applyAsDouble(y, x);
518    }
519
520    /**
521     * @param x Number.
522     * @return atanh(x).
523     */
524    public static double atanh(double x) {
525        return ATANH.applyAsDouble(x);
526    }
527
528    /**
529     * @param x Number.
530     * @return cbrt(x).
531     *
532     * @see Math#cbrt(double)
533     */
534    public static double cbrt(double x) {
535        return CBRT.applyAsDouble(x);
536    }
537
538    /**
539     * @param x Number.
540     * @return ceil(x).
541     *
542     * @see Math#ceil(double)
543     */
544    public static double ceil(double x) {
545        return CEIL.applyAsDouble(x);
546    }
547
548    /**
549     * @param x Number.
550     * @param y Number.
551     * @return copySign(x, y).
552     *
553     * @see Math#copySign(float,float)
554     */
555    public static float copySign(float x,
556                                 float y) {
557        return COPYSIGN_FLOAT.applyAsFloat(x, y);
558    }
559
560    /**
561     * @param x Number.
562     * @param y Number.
563     * @return copySign(x, y).
564     *
565     * @see Math#copySign(double,double)
566     */
567    public static double copySign(double x,
568                                  double y) {
569        return COPYSIGN_DOUBLE.applyAsDouble(x, y);
570    }
571
572    /**
573     * @param x Number.
574     * @return cos(x).
575     *
576     * @see Math#cos(double)
577     */
578    public static double cos(double x) {
579        return COS.applyAsDouble(x);
580    }
581
582    /**
583     * @param x Number.
584     * @return cosh(x).
585     *
586     * @see Math#cosh(double)
587     */
588    public static double cosh(double x) {
589        return COSH.applyAsDouble(x);
590    }
591
592    /**
593     * @param x Number.
594     * @return decrementExact(x).
595     *
596     * @see Math#decrementExact(int)
597     */
598    public static int decrementExact(int x) {
599        return DECREMENTEXACT_INT.applyAsInt(x);
600    }
601
602    /**
603     * @param x Number.
604     * @return decrementExact(x).
605     *
606     * @see Math#decrementExact(long)
607     */
608    public static long decrementExact(long x) {
609        return DECREMENTEXACT_LONG.applyAsLong(x);
610    }
611
612    /**
613     * @param x Number.
614     * @return exp(x).
615     *
616     * @see Math#exp(double)
617     */
618    public static double exp(double x) {
619        return EXP.applyAsDouble(x);
620    }
621
622    /**
623     * @param x Number.
624     * @return expm1(x).
625     *
626     * @see Math#expm1(double)
627     */
628    public static double expm1(double x) {
629        return EXPM1.applyAsDouble(x);
630    }
631
632    /**
633     * @param x Number.
634     * @return floor(x).
635     *
636     * @see Math#floor(double)
637     */
638    public static double floor(double x) {
639        return FLOOR.applyAsDouble(x);
640    }
641
642    /**
643     * @param x Number.
644     * @param y Number.
645     * @return floorDiv(x, y).
646     *
647     * @see Math#floorDiv(int,int)
648     */
649    public static int floorDiv(int x,
650                               int y) {
651        return FLOORDIV_INT.applyAsInt(x, y);
652    }
653
654    /**
655     * @param x Number.
656     * @param y Number.
657     * @return floorDiv(x, y).
658     *
659     * @see Math#floorDiv(long,long)
660     */
661    public static long floorDiv(long x,
662                                long y) {
663        return FLOORDIV_LONG.applyAsLong(x, y);
664    }
665
666    /**
667     * @param x Number.
668     * @param y Number.
669     * @return floorMod(x, y).
670     *
671     * @see Math#floorMod(int,int)
672     */
673    public static int floorMod(int x,
674                               int y) {
675        return FLOORMOD_INT.applyAsInt(x, y);
676    }
677
678    /**
679     * @param x Number.
680     * @param y Number.
681     * @return floorMod(x, y).
682     *
683     * @see Math#floorMod(long,long)
684     */
685    public static long floorMod(long x,
686                                long y) {
687        return FLOORMOD_LONG.applyAsLong(x, y);
688    }
689
690    /**
691     * @param x Number.
692     * @return getExponent(x).
693     *
694     * @see Math#getExponent(float)
695     */
696    public static int getExponent(float x) {
697        return GETEXPONENT_FLOAT.applyAsInt(x);
698    }
699
700    /**
701     * @param x Number.
702     * @return getExponent(x).
703     *
704     * @see Math#getExponent(double)
705     */
706    public static int getExponent(double x) {
707        return GETEXPONENT_DOUBLE.applyAsInt(x);
708    }
709
710    /**
711     * @param x Number.
712     * @param y Number.
713     * @return hypot(x, y).
714     *
715     * @see Math#hypot(double,double)
716     */
717    public static double hypot(double x,
718                               double y) {
719        return HYPOT.applyAsDouble(x, y);
720    }
721
722    /**
723     * @param x Number.
724     * @param y Number.
725     * @return IEEEremainder(x, y).
726     *
727     * @see Math#IEEEremainder(double,double)
728     */
729    public static double IEEEremainder(double x,
730                                       double y) {
731        return IEEEREMAINDER.applyAsDouble(x, y);
732    }
733
734    /**
735     * @param x Number.
736     * @return incrementExact(x).
737     *
738     * @see Math#incrementExact(int)
739     */
740    public static int incrementExact(int x) {
741        return INCREMENTEXACT_INT.applyAsInt(x);
742    }
743
744    /**
745     * @param x Number.
746     * @return incrementExact(x).
747     *
748     * @see Math#incrementExact(long)
749     */
750    public static long incrementExact(long x) {
751        return INCREMENTEXACT_LONG.applyAsLong(x);
752    }
753
754    /**
755     * @param x Number.
756     * @return log(x).
757     *
758     * @see Math#log(double)
759     */
760    public static double log(double x) {
761        return LOG.applyAsDouble(x);
762    }
763
764    /**
765     * @param x Number.
766     * @return log10(x).
767     *
768     * @see Math#log10(double)
769     */
770    public static double log10(double x) {
771        return LOG10.applyAsDouble(x);
772    }
773
774    /**
775     * @param x Number.
776     * @return log1p(x).
777     *
778     * @see Math#log1p(double)
779     */
780    public static double log1p(double x) {
781        return LOG1P.applyAsDouble(x);
782    }
783
784    /**
785     * @param x Number.
786     * @param y Number.
787     * @return max(x, y).
788     *
789     * @see Math#max(int,int)
790     */
791    public static int max(int x,
792                          int y) {
793        return MAX_INT.applyAsInt(x, y);
794    }
795
796    /**
797     * @param x Number.
798     * @param y Number.
799     * @return max(x, y).
800     *
801     * @see Math#max(long,long)
802     */
803    public static long max(long x,
804                           long y) {
805        return MAX_LONG.applyAsLong(x, y);
806    }
807
808    /**
809     * @param x Number.
810     * @param y Number.
811     * @return max(x, y).
812     *
813     * @see Math#max(float,float)
814     */
815    public static float max(float x,
816                            float y) {
817        return MAX_FLOAT.applyAsFloat(x, y);
818    }
819
820    /**
821     * @param x Number.
822     * @param y Number.
823     * @return max(x, y).
824     *
825     * @see Math#max(double,double)
826     */
827    public static double max(double x,
828                             double y) {
829        return MAX_DOUBLE.applyAsDouble(x, y);
830    }
831
832    /**
833     * @param x Number.
834     * @param y Number.
835     * @return min(x, y).
836     *
837     * @see Math#min(int,int)
838     */
839    public static int min(int x,
840                          int y) {
841        return MIN_INT.applyAsInt(x, y);
842    }
843
844    /**
845     * @param x Number.
846     * @param y Number.
847     * @return min(x, y).
848     *
849     * @see Math#min(long,long)
850     */
851    public static long min(long x,
852                           long y) {
853        return MIN_LONG.applyAsLong(x, y);
854    }
855
856    /**
857     * @param x Number.
858     * @param y Number.
859     * @return min(x, y).
860     *
861     * @see Math#min(float,float)
862     */
863    public static float min(float x,
864                            float y) {
865        return MIN_FLOAT.applyAsFloat(x, y);
866    }
867
868    /**
869     * @param x Number.
870     * @param y Number.
871     * @return min(x, y).
872     *
873     * @see Math#min(double,double)
874     */
875    public static double min(double x,
876                             double y) {
877        return MIN_DOUBLE.applyAsDouble(x, y);
878    }
879
880    /**
881     * @param x Number.
882     * @param y Number.
883     * @return multiplyExact(x, y).
884     *
885     * @see Math#multiplyExact(int,int)
886     */
887    public static int multiplyExact(int x,
888                                    int y) {
889        return MULTIPLYEXACT_INT.applyAsInt(x, y);
890    }
891
892    /**
893     * @param x Number.
894     * @param y Number.
895     * @return multiplyExact(x, y).
896     *
897     * @see Math#multiplyExact(long,long)
898     */
899    public static long multiplyExact(long x,
900                                     long y) {
901        return MULTIPLYEXACT_LONG.applyAsLong(x, y);
902    }
903
904    /**
905     * @param x Number.
906     * @return negateExact(x).
907     *
908     * @see Math#negateExact(int)
909     */
910    public static int negateExact(int x) {
911        return NEGATEEXACT_INT.applyAsInt(x);
912    }
913
914    /**
915     * @param x Number.
916     * @return negateExact(x).
917     *
918     * @see Math#negateExact(long)
919     */
920    public static long negateExact(long x) {
921        return NEGATEEXACT_LONG.applyAsLong(x);
922    }
923
924    /**
925     * @param x Number.
926     * @param y Number.
927     * @return nextAfter(x, y).
928     *
929     * @see Math#nextAfter(double, double)
930     */
931    public static double nextAfter(double x,
932                                   double y) {
933        return NEXTAFTER_DOUBLE.applyAsDouble(x, y);
934    }
935
936    /**
937     * @param x Number.
938     * @param y Number.
939     * @return nextAfter(x, y).
940     *
941     * @see Math#nextAfter(float,double)
942     */
943    public static float nextAfter(float x,
944                                  double y) {
945        return NEXTAFTER_FLOAT.applyAsFloat(x, y);
946    }
947
948    /**
949     * @param x Number.
950     * @return nextDown(x).
951     *
952     * @see Math#nextDown(double)
953     */
954    public static double nextDown(double x) {
955        return NEXTDOWN_DOUBLE.applyAsDouble(x);
956    }
957
958    /**
959     * @param x Number.
960     * @return nextDown(x).
961     *
962     * @see Math#nextDown(float)
963     */
964    public static float nextDown(float x) {
965        return NEXTDOWN_FLOAT.applyAsFloat(x);
966    }
967
968    /**
969     * @param x Number.
970     * @return nextUp(x).
971     *
972     * @see Math#nextUp(double)
973     */
974    public static double nextUp(double x) {
975        return NEXTUP_DOUBLE.applyAsDouble(x);
976    }
977
978    /**
979     * @param x Number.
980     * @return nextUp(x).
981     *
982     * @see Math#nextUp(float)
983     */
984    public static float nextUp(float x) {
985        return NEXTUP_FLOAT.applyAsFloat(x);
986    }
987
988    /**
989     * @param x Number.
990     * @param y Number.
991     * @return pow(x, y).
992     *
993     * @see Math#pow(double,double)
994     */
995    public static double pow(double x,
996                             double y) {
997        return POW.applyAsDouble(x, y);
998    }
999
1000    /**
1001     * @return a random number between 0 and 1.
1002     *
1003     * @see Math#random()
1004     */
1005    public static double random() {
1006        return RANDOM.getAsDouble();
1007    }
1008
1009    /**
1010     * @param x Number.
1011     * @return rint(x).
1012     *
1013     * @see Math#rint(double)
1014     */
1015    public static double rint(double x) {
1016        return RINT.applyAsDouble(x);
1017    }
1018
1019    /**
1020     * @param x Number.
1021     * @return round(x).
1022     *
1023     * @see Math#round(float)
1024     */
1025    public static int round(float x) {
1026        return ROUND_FLOAT.applyAsInt(x);
1027    }
1028
1029    /**
1030     * @param x Number.
1031     * @return round(x).
1032     *
1033     * @see Math#round(double)
1034     */
1035    public static long round(double x) {
1036        return ROUND_DOUBLE.applyAsLong(x);
1037    }
1038
1039    /**
1040     * @param x Number.
1041     * @param y Number.
1042     * @return scalb(x, y).
1043     *
1044     * @see Math#scalb(double,int)
1045     */
1046    public static double scalb(double x,
1047                               int y) {
1048        return SCALB_DOUBLE.applyAsDouble(x, y);
1049    }
1050
1051    /**
1052     * @param x Number.
1053     * @param y Number.
1054     * @return scalb(x, y).
1055     *
1056     * @see Math#scalb(float,int)
1057     */
1058    public static float scalb(float x,
1059                              int y) {
1060        return SCALB_FLOAT.applyAsFloat(x, y);
1061    }
1062
1063    /**
1064     * @param x Number.
1065     * @return signum(x).
1066     *
1067     * @see Math#signum(double)
1068     */
1069    public static double signum(double x) {
1070        return SIGNUM_DOUBLE.applyAsDouble(x);
1071    }
1072
1073    /**
1074     * @param x Number.
1075     * @return signum(x).
1076     *
1077     * @see Math#signum(float)
1078     */
1079    public static float signum(float x) {
1080        return SIGNUM_FLOAT.applyAsFloat(x);
1081    }
1082
1083    /**
1084     * @param x Number.
1085     * @return sin(x).
1086     *
1087     * @see Math#sin(double)
1088     */
1089    public static double sin(double x) {
1090        return SIN.applyAsDouble(x);
1091    }
1092
1093    /**
1094     * @param x Number.
1095     * @return sinh(x).
1096     *
1097     * @see Math#sinh(double)
1098     */
1099    public static double sinh(double x) {
1100        return SINH.applyAsDouble(x);
1101    }
1102
1103    /**
1104     * @param x Number.
1105     * @return sqrt(x).
1106     *
1107     * @see Math#sqrt(double)
1108     */
1109    public static double sqrt(double x) {
1110        return SQRT.applyAsDouble(x);
1111    }
1112
1113    /**
1114     * @param x Number.
1115     * @param y Number.
1116     * @return subtractExact(x, y).
1117     *
1118     * @see Math#subtractExact(int,int)
1119     */
1120    public static int subtractExact(int x,
1121                                    int y) {
1122        return SUBTRACTEXACT_INT.applyAsInt(x, y);
1123    }
1124
1125    /**
1126     * @param x Number.
1127     * @param y Number.
1128     * @return subtractExact(x, y).
1129     *
1130     * @see Math#subtractExact(long,long)
1131     */
1132    public static long subtractExact(long x,
1133                                     long y) {
1134        return SUBTRACTEXACT_LONG.applyAsLong(x, y);
1135    }
1136
1137    /**
1138     * @param x Number.
1139     * @return tan(x).
1140     *
1141     * @see Math#tan(double)
1142     */
1143    public static double tan(double x) {
1144        return TAN.applyAsDouble(x);
1145    }
1146
1147    /**
1148     * @param x Number.
1149     * @return tanh(x).
1150     *
1151     * @see Math#tanh(double)
1152     */
1153    public static double tanh(double x) {
1154        return TANH.applyAsDouble(x);
1155    }
1156
1157    /**
1158     * @param x Number.
1159     * @return toDegrees(x).
1160     *
1161     * @see Math#toDegrees(double)
1162     */
1163    public static double toDegrees(double x) {
1164        return TODEGREES.applyAsDouble(x);
1165    }
1166
1167    /**
1168     * @param x Number.
1169     * @return toIntExact(x).
1170     *
1171     * @see Math#toIntExact(long)
1172     */
1173    public static int toIntExact(long x) {
1174        return TOINTEXACT.applyAsInt(x);
1175    }
1176
1177    /**
1178     * @param x Number.
1179     * @return toRadians(x).
1180     *
1181     * @see Math#toRadians(double)
1182     */
1183    public static double toRadians(double x) {
1184        return TORADIANS.applyAsDouble(x);
1185    }
1186
1187    /**
1188     * @param x Number.
1189     * @return ulp(x).
1190     *
1191     * @see Math#ulp(double)
1192     */
1193    public static double ulp(double x) {
1194        return ULP_DOUBLE.applyAsDouble(x);
1195    }
1196
1197    /**
1198     * @param x Number.
1199     * @return ulp(x).
1200     *
1201     * @see Math#ulp(float)
1202     */
1203    public static float ulp(float x) {
1204        return ULP_FLOAT.applyAsFloat(x);
1205    }
1206
1207    /** Interface missing from "java.util.function" package. */
1208    private interface FloatUnaryOperator {
1209        /**
1210         * @param x Operand.
1211         * @return the result of applying this operator.
1212         */
1213        float applyAsFloat(float x);
1214    }
1215
1216    /** Interface missing from "java.util.function" package. */
1217    private interface FloatBinaryOperator {
1218        /**
1219         * @param x Operand.
1220         * @param y Operand.
1221         * @return the result of applying this operator.
1222         */
1223        float applyAsFloat(float x, float y);
1224    }
1225
1226    /** Interface missing from "java.util.function" package. */
1227    private interface FloatDouble2FloatOperator {
1228        /**
1229         * @param x Operand.
1230         * @param y Operand.
1231         * @return the result of applying this operator.
1232         */
1233        float applyAsFloat(float x, double y);
1234    }
1235
1236    /** Interface missing from "java.util.function" package. */
1237    private interface FloatToIntFunction {
1238        /**
1239         * @param x Operand.
1240         * @return the result of applying this operator.
1241         */
1242        int applyAsInt(float x);
1243    }
1244
1245    /** Interface missing from "java.util.function" package. */
1246    private interface FloatInt2FloatOperator {
1247        /**
1248         * @param x Operand.
1249         * @param y Operand.
1250         * @return the result of applying this operator.
1251         */
1252        float applyAsFloat(float x, int y);
1253    }
1254
1255    /** Interface missing from "java.util.function" package. */
1256    private interface DoubleInt2DoubleOperator {
1257        /**
1258         * @param x Operand.
1259         * @param y Operand.
1260         * @return the result of applying this operator.
1261         */
1262        double applyAsDouble(double x, int y);
1263    }
1264}