diff --git a/.gitignore b/.gitignore index 78d79f265..c284ca24b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /lib/ /bin/ /.shards/ +.vscode \ No newline at end of file diff --git a/core/source/Math.mint b/core/source/Math.mint index 3d0a50f6d..899e2476f 100644 --- a/core/source/Math.mint +++ b/core/source/Math.mint @@ -1,5 +1,29 @@ /* Mathematical functions. */ module Math { + /* Euler's number and the base of natural logarithms; approximately `2.718`. */ + const E = `Math.E` + + /* Natural logarithm of `10`; approximately `2.303`. */ + const LN10 = `Math.LN10` + + /* Natural logarithm of `2`; approximately `0.693`. */ + const LN2 = `Math.LN2` + + /* Base-10 logarithm of `E`; approximately `0.434`. */ + const LOG10E = `Math.LOG10E` + + /* Base-2 logarithm of `E`; approximately `1.443`. */ + const LOG2E = `Math.LOG2E` + + /* Ratio of a circle's circumference to its diameter; approximately `3.14159`. */ + const PI = `Math.PI` + + /* Square root of `0.5`; approximately `0.707`. */ + const SQRT12 = `Math.SQRT1_2` + + /* Square root of `2`; approximately `1.414`. */ + const SQRT2 = `Math.SQRT2` + /* Returns the absolute value of the given number. @@ -10,6 +34,51 @@ module Math { `Math.abs(#{number})` } + /* Returns the inverse cosine of the given angle in radians */ + fun acos (number : Number) : Number { + `Math.acos(#{number})` + } + + /* Returns the inverse hyperbolic cosine of the given angle in radians */ + fun acosh (number : Number) : Number { + `Math.acosh(#{number})` + } + + /* Returns the inverse sine of the given angle in radians */ + fun asin (number : Number) : Number { + `Math.asin(#{number})` + } + + /* Returns the inverse hyperbolic sine of the given angle in radians */ + fun asinh (number : Number) : Number { + `Math.asinh(#{number})` + } + + /* Returns the inverse tangent of the given angle in radians */ + fun atan (number : Number) : Number { + `Math.atan(#{number})` + } + + /* Returns the angle in the plane (in radians) between the positive x-axis and the ray from (0, 0) to the point (x, y) */ + fun atan2 (y : Number, x : Number) : Number { + `Math.atan2(#{y}, #{x})` + } + + /* Returns the inverse hyperbolic tangent of the given angle in radians */ + fun atanh (number : Number) : Number { + `Math.atanh(#{number})` + } + + /* + Returns the cubic root of the given number + + Math.cbrt(1) == 1 + Math.cbrt(64) == 4 + */ + fun cbrt (number : Number) : Number { + `Math.cbrt(#{number})` + } + /* Returns the smallest integer greater than or equal to the given number. @@ -29,6 +98,41 @@ module Math { Math.min(upper, Math.max(lower, value)) } + /* + Returns the number of leading zero bits in the 32-bit binary representation of a number + + 00000000000000000000000000000100 + Math.clz32(4) == 29 + */ + fun clz32 (number : Number) : Number { + `Math.clz32(#{number})` + } + + /* Returns the cosine of the given angle in radians */ + fun cos (number : Number) : Number { + `Math.cos(#{number})` + } + + /* Returns the hyperbolic cosine of the given angle in radians */ + fun cosh (number : Number) : Number { + `Math.cosh(#{number})` + } + + /* Returns the value of `Math:E` raised to the power x, where x is the given number */ + fun exp (x : Number) : Number { + `Math.exp(#{x})` + } + + /* + Returns the value of `Math:E` to the power x, minus 1 + + Math.exp(2) == 7.38905609893065 + Math.expm1(2) == 6.38905609893065 + */ + fun expm1 (x : Number) : Number { + `Math.expm1(#{x})` + } + /* Returns the largest integer less than or equal to the given number. @@ -48,6 +152,65 @@ module Math { `Number((#{b} - (Math.floor(#{b} / #{a}) * #{a})).toPrecision(8))` } + /* Returns the nearest 32-bit single precision float representation of the given number. */ + fun fround (number : Number) : Number { + `Math.fround(#{number})` + } + + /* + Returns the square root of the sum of squares of its arguments. + + Math.hypot(3, 4) == 5 + */ + fun hypot (a : Number, b : Number) : Number { + `Math.hypot(#{a}, #{b})` + } + + /* + Returns the result using C-like 32-bit multiplication of the two parameters. + + Math.imul(3, 4) == 12 + */ + fun imul (a : Number, b : number) : Number { + `Math.imul(#{a}, #{b})` + } + + /* + Returns natural logarithm (base e) of the given value + + Math.log(1) == 0 + */ + fun log (number : Number) : Number { + `Math.log(#{number})` + } + + /* + Returns natural logarithm (base 10) of the given value + + Math.log10(100) == 10 + */ + fun log10 (number : Number) : Number { + `Math.log10(#{number})` + } + + /* + Returns natural logarithm (base e) of the given value, plus 1 + + Math.log1p(1) == 0 + */ + fun log1p (number : Number) : Number { + `Math.log1p(#{number})` + } + + /* + Returns natural logarithm (base 2) of the given value + + Math.log2(8) == 3 + */ + fun log2 (number : Number) : Number { + `Math.log2(#{number})` + } + /* Returns the highest-valued number from the arguments. @@ -98,6 +261,26 @@ module Math { `Math.round(#{number})` } + /* + Returns the sign of the given number (1 or -1) + + Math.sign(5) == 1 + Math.sign(-5) == -1 + */ + fun sign (number : Number) : Number { + `Math.sign(#{number})` + } + + /* Calculates the sine of the given angle in radians */ + fun sin (value : Number) : Number { + `Math.sin(#{value})` + } + + /* Calculates the hyperbolic sine of the given angle in radians */ + fun sinh (number : Number) : Number { + `Math.sinh(#{number})` + } + /* Returns the square root of the given number @@ -107,6 +290,16 @@ module Math { `Math.sqrt(#{value})` } + /* Calculates the tangent of the given angle in radians */ + fun tan (number : Number) { + `Math.tan(#{number})` + } + + /* Calculates the hyperbolic tangent of the given angle in radians */ + fun tanh (number : Number) : Number { + `Math.tanh(#{number})` + } + /* Returns the integer part of a number by removing any fractional digits. diff --git a/core/tests/tests/Math.mint b/core/tests/tests/Math.mint index 49249dce7..3bd3b6238 100644 --- a/core/tests/tests/Math.mint +++ b/core/tests/tests/Math.mint @@ -100,3 +100,182 @@ suite "Math.random" { n >= 0.0 && n < 1.0 } } + +suite "Math:E" { + test "returns Math.E" { + Math:E == `Math.E` + } +} + +suite "Math:LN2" { + test "returns Math.LN2" { + Math:LN2 == `Math.LN2` + } +} + +suite "Math:LN10" { + test "returns Math.LN10" { + Math:LN10 == `Math.LN10` + } +} + +suite "Math:LOG2E" { + test "returns Math.LOG2E" { + Math:LOG2E == `Math.LOG2E` + } +} + +suite "Math:LOG10E" { + test "returns Math.LOG10E" { + Math:LOG10E == `Math.LOG10E` + } +} + +suite "Math:PI" { + test "returns Math.PI" { + Math:PI == `Math.PI` + } +} + +suite "Math:SQRT12" { + test "returns Math.SQRT12" { + Math:SQRT12 == `Math.SQRT1_2` + } +} + +suite "Math:SQRT2" { + test "returns Math.SQRT2" { + Math:SQRT2 == `Math.SQRT2` + } +} + +suite "Math.acos" { + test "it returns the inverse cosine of an angle in radians" { + Math.acos(1) == `Math.acos(1)` + } +} + +suite "Math.acosh" { + test "it returns the inverse hyperbolic cosine of an angle in radians" { + Math.acosh(1) == `Math.acosh(1)` + } +} + +suite "Math.asin" { + test "it returns the inverse sine of an angle in radians" { + Math.asin(1) == `Math.asin(1)` + } +} + +suite "Math.asinh" { + test "it returns the inverse hyperbolic sine of an angle in radians" { + Math.asinh(1) == `Math.asinh(1)` + } +} + +suite "Math.atan" { + test "it returns the inverse tangent of an angle in radians" { + Math.atan(1) == `Math.atan(1)` + } +} + +suite "Math.atan2" { + test "it returns the angle in the plane (in radians) between the positive x-axis and the ray from (0, 0) to the point (x, y)" { + Math.atan2(3, 4) == `Math.atan2(3, 4)` + } +} + +suite "Math.atanh" { + test "it returns the inverse hyperbolic tangent of an angle in radians" { + Math.atanh(1) == `Math.atanh(1)` + } +} + +suite "Math.cbrt" { + test "it returns the cubic root" { + Math.cbrt(8) == `Math.cbrt(8)` + } +} + +suite "Math.clz32" { + test "it returns the sin of an angle in radians" { + Math.clz32(4) == `Math.clz32(4)` + } +} + +suite "Math.cos" { + test "it returns the cosine of an angle in radians" { + Math.cos(1) == `Math.cos(1)` + } +} + +suite "Math.cosh" { + test "it returns the hyperbolic cosine of an angle in radians" { + Math.cosh(1) == `Math.cosh(1)` + } +} + +suite "Math.exp" { + test "it returns e raised to the power of x, where x is the number provided" { + Math.exp(2) == `Math.exp(2)` + } +} + +suite "Math.expm1" { + test "it returns e raised to the power of x - 1, where x is the number provided" { + Math.expm1(2) == `Math.expm1(2)` + } +} + +suite "Math.fround" { + test "returns the nearest 32-bit single precision float representation of a number" { + Math.fround(5.5) == `Math.fround(5.5)` + Math.fround(5.05) == `Math.fround(5.05)` + } +} + +suite "Math.hypot" { + test "returns the square root of the sum of squares of two numbers" { + Math.hypot(3, 4) == 5 + } +} + +suite "Math.imul" { + test "multiples two numbers using C-like 32-bit multiplication" { + Math.imul(-5, 12) == -60 + } +} + +suite "Math.log" { + test "returns the natural log (base e) of a number" { + Math.log(Math:E) == 1 + } +} + +suite "Math.log1p" { + test "returns the natural log (base e) of x + 1, where x is the provided value" { + Math.log1p(Math:E) == `Math.log1p(#{Math:E})` + } +} + +suite "Math.log2" { + test "returns the natural log (base 2) of a number" { + Math.log2(8) == 3 + } +} + +suite "Math.log10" { + test "it returns the natural log (base 10) of a number" { + Math.log10(100) == 2 + } +} + +suite "Math.sign" { + test "it returns the sign (1 or -1) of a number" { + Math.sign(5) == 1 + } + + test "it returns the sign (1 or -1) of a number #2" { + Math.sign(-5) == -1 + } +}