2626 * Math utility methods and constants.
2727 */
2828public final class Math {
29- // The following methods are not implemented because JS doesn't provide the
30- // necessary pieces:
31- // public static double ulp (double x)
32- // public static float ulp (float x)
33- // public static int getExponent (double d)
34- // public static int getExponent (float f)
3529
3630 public static final double E = 2.7182818284590452354 ;
3731 public static final double PI = 3.14159265358979323846 ;
@@ -87,9 +81,8 @@ public static long addExact(long x, long y) {
8781 @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.atan2" )
8882 public static native double atan2 (double y , double x );
8983
90- public static double cbrt (double x ) {
91- return x == 0 || !Double .isFinite (x ) ? x : pow (x , 1.0 / 3.0 );
92- }
84+ @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.cbrt" )
85+ public static native double cbrt (double x );
9386
9487 @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.ceil" )
9588 public static native double ceil (double x );
@@ -109,9 +102,8 @@ public static float copySign(float magnitude, float sign) {
109102 @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.cos" )
110103 public static native double cos (double x );
111104
112- public static double cosh (double x ) {
113- return (exp (x ) + exp (-x )) / 2 ;
114- }
105+ @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.cosh" )
106+ public static native double cosh (double x );
115107
116108 public static int decrementExact (int x ) {
117109 checkCriticalArithmetic (x != Integer .MIN_VALUE );
@@ -144,6 +136,10 @@ public static long floorDiv(long dividend, long divisor) {
144136 return ((dividend ^ divisor ) >= 0 ? dividend / divisor : ((dividend + 1 ) / divisor ) - 1 );
145137 }
146138
139+ public static long floorDiv (long dividend , int divisor ) {
140+ return floorDiv (dividend , (long ) divisor );
141+ }
142+
147143 public static int floorMod (int dividend , int divisor ) {
148144 checkCriticalArithmetic (divisor != 0 );
149145 return ((dividend % divisor ) + divisor ) % divisor ;
@@ -154,6 +150,10 @@ public static long floorMod(long dividend, long divisor) {
154150 return ((dividend % divisor ) + divisor ) % divisor ;
155151 }
156152
153+ public static long floorMod (long dividend , int divisor ) {
154+ return floorMod (dividend , (long ) divisor );
155+ }
156+
157157 @ SuppressWarnings ("CheckStyle.MethodName" )
158158 public static double IEEEremainder (double v , double m ) {
159159 double ratio = v / m ;
@@ -175,6 +175,25 @@ public static int getExponent(float v) {
175175 return ((JsUtils .floatToRawIntBits (v ) >> 23 ) & 255 ) - Float .MAX_EXPONENT ;
176176 }
177177
178+ public static double ulp (double v ) {
179+ if (!Double .isFinite (v )) {
180+ return Math .abs (v );
181+ }
182+ int exponent = Math .getExponent (v );
183+ if (exponent == -1023 ) {
184+ return Double .MIN_VALUE ;
185+ }
186+ return Math .pow (2 , exponent - 52 );
187+ }
188+
189+ public static float ulp (float v ) {
190+ int exponent = Math .getExponent (v );
191+ if (exponent == -Float .MAX_EXPONENT ) {
192+ return Float .MIN_VALUE ;
193+ }
194+ return (float ) Math .pow (2 , exponent - 23 );
195+ }
196+
178197 @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.hypot" )
179198 public static native double hypot (double x , double y );
180199
@@ -191,9 +210,8 @@ public static long incrementExact(long x) {
191210 @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.log" )
192211 public static native double log (double x );
193212
194- public static double log10 (double x ) {
195- return log (x ) * NativeMath .LOG10E ;
196- }
213+ @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.log10" )
214+ public static native double log10 (double x );
197215
198216 @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.log1p" )
199217 public static native double log1p (double x );
@@ -224,12 +242,28 @@ public static long min(long x, long y) {
224242 return x < y ? x : y ;
225243 }
226244
245+ public static long multiplyFull (int x , int y ) {
246+ return (long ) x * (long ) y ;
247+ }
248+
227249 public static int multiplyExact (int x , int y ) {
228250 double r = (double ) x * (double ) y ;
229251 checkCriticalArithmetic (isSafeIntegerRange (r ));
230252 return (int ) r ;
231253 }
232254
255+ public static long multiplyExact (long x , int y ) {
256+ if (y == -1 ) {
257+ return negateExact (x );
258+ }
259+ if (y == 0 ) {
260+ return 0 ;
261+ }
262+ long r = x * y ;
263+ checkCriticalArithmetic (r / y == x );
264+ return r ;
265+ }
266+
233267 public static long multiplyExact (long x , long y ) {
234268 if (y == -1 ) {
235269 return negateExact (x );
@@ -311,13 +345,8 @@ public static float scalb(float f, int scaleFactor) {
311345 return (float ) scalb ((double ) f , scaleFactor );
312346 }
313347
314- public static double signum (double d ) {
315- if (d == 0 || Double .isNaN (d )) {
316- return d ;
317- } else {
318- return d < 0 ? -1 : 1 ;
319- }
320- }
348+ @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.sign" )
349+ public static native double signum (double d );
321350
322351 public static float signum (float f ) {
323352 return (float ) signum ((double ) f );
@@ -326,28 +355,17 @@ public static float signum(float f) {
326355 @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.sin" )
327356 public static native double sin (double x );
328357
329- public static double sinh (double x ) {
330- return x == 0.0 ? x : (exp (x ) - exp (-x )) / 2 ;
331- }
358+ @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.sinh" )
359+ public static native double sinh (double x );
332360
333361 @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.sqrt" )
334362 public static native double sqrt (double x );
335363
336364 @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.tan" )
337365 public static native double tan (double x );
338366
339- public static double tanh (double x ) {
340- if (x == 0.0 ) {
341- // -0.0 should return -0.0.
342- return x ;
343- }
344-
345- double e2x = exp (2 * x );
346- if (Double .isInfinite (e2x )) {
347- return 1 ;
348- }
349- return (e2x - 1 ) / (e2x + 1 );
350- }
367+ @ JsMethod (namespace = JsPackage .GLOBAL , name = "Math.tanh" )
368+ public static native double tanh (double x );
351369
352370 public static double toDegrees (double x ) {
353371 return x * PI_UNDER_180 ;
@@ -438,7 +456,6 @@ private static boolean isSafeIntegerRange(double value) {
438456
439457 @ JsType (isNative = true , name = "Math" , namespace = JsPackage .GLOBAL )
440458 private static class NativeMath {
441- public static double LOG10E ;
442459 public static native double round (double x );
443460 }
444461}
0 commit comments