diff --git a/vlib/math/math.c.v b/vlib/math/math.c.v new file mode 100644 index 0000000000..30f6bb7bed --- /dev/null +++ b/vlib/math/math.c.v @@ -0,0 +1,256 @@ +// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +module math + +#include + +fn C.acos(x f64) f64 +fn C.asin(x f64) f64 +fn C.atan(x f64) f64 +fn C.atan2(y f64, x f64) f64 +fn C.cbrt(x f64) f64 +fn C.ceil(x f64) f64 +fn C.cos(x f64) f64 +fn C.cosf(x f32) f32 +fn C.cosh(x f64) f64 +fn C.erf(x f64) f64 +fn C.erfc(x f64) f64 +fn C.exp(x f64) f64 +fn C.exp2(x f64) f64 +fn C.fabs(x f64) f64 +fn C.floor(x f64) f64 +fn C.fmod(x f64, y f64) f64 +fn C.hypot(x f64, y f64) f64 +fn C.log(x f64) f64 +fn C.log2(x f64) f64 +fn C.log10(x f64) f64 +fn C.lgamma(x f64) f64 +fn C.pow(x f64, y f64) f64 +fn C.powf(x f32, y f32) f32 +fn C.round(x f64) f64 +fn C.sin(x f64) f64 +fn C.sinf(x f32) f32 +fn C.sinh(x f64) f64 +fn C.sqrt(x f64) f64 +fn C.sqrtf(x f32) f32 +fn C.tgamma(x f64) f64 +fn C.tan(x f64) f64 +fn C.tanf(x f32) f32 +fn C.tanh(x f64) f64 +fn C.trunc(x f64) f64 + +// NOTE +// When adding a new function, please make sure it's in the right place. +// All functions are sorted alphabetically. + +// Returns the absolute value. +[inline] +pub fn abs(a f64) f64 { + return C.fabs(a) +} + +// acos calculates inverse cosine (arccosine). +[inline] +pub fn acos(a f64) f64 { + return C.acos(a) +} + +// asin calculates inverse sine (arcsine). +[inline] +pub fn asin(a f64) f64 { + return C.asin(a) +} + +// atan calculates inverse tangent (arctangent). +[inline] +pub fn atan(a f64) f64 { + return C.atan(a) +} + +// atan2 calculates inverse tangent with two arguments, returns the angle between the X axis and the point. +[inline] +pub fn atan2(a, b f64) f64 { + return C.atan2(a, b) +} + +// cbrt calculates cubic root. +[inline] +pub fn cbrt(a f64) f64 { + return C.cbrt(a) +} + +// ceil returns the nearest f64 greater or equal to the provided value. +[inline] +pub fn ceil(a f64) f64 { + return C.ceil(a) +} + +// cos calculates cosine. +[inline] +pub fn cos(a f64) f64 { + return C.cos(a) +} + +// cosf calculates cosine. (float32) +[inline] +pub fn cosf(a f32) f32 { + return C.cosf(a) +} + +// cosh calculates hyperbolic cosine. +[inline] +pub fn cosh(a f64) f64 { + return C.cosh(a) +} + +// exp calculates exponent of the number (math.pow(math.E, a)). +[inline] +pub fn exp(a f64) f64 { + return C.exp(a) +} + +// erf computes the error function value +[inline] +pub fn erf(a f64) f64 { + return C.erf(a) +} + +// erfc computes the complementary error function value +[inline] +pub fn erfc(a f64) f64 { + return C.erfc(a) +} + +// exp2 returns the base-2 exponential function of a (math.pow(2, a)). +[inline] +pub fn exp2(a f64) f64 { + return C.exp2(a) +} + +// floor returns the nearest f64 lower or equal of the provided value. +[inline] +pub fn floor(a f64) f64 { + return C.floor(a) +} + +// fmod returns the floating-point remainder of number / denom (rounded towards zero): +[inline] +pub fn fmod(a, b f64) f64 { + return C.fmod(a, b) +} + +// gamma computes the gamma function value +[inline] +pub fn gamma(a f64) f64 { + return C.tgamma(a) +} + +// Returns hypotenuse of a right triangle. +[inline] +pub fn hypot(a, b f64) f64 { + return C.hypot(a, b) +} + +// log calculates natural (base-e) logarithm of the provided value. +[inline] +pub fn log(a f64) f64 { + return C.log(a) +} + +// log2 calculates base-2 logarithm of the provided value. +[inline] +pub fn log2(a f64) f64 { + return C.log2(a) +} + +// log10 calculates the common (base-10) logarithm of the provided value. +[inline] +pub fn log10(a f64) f64 { + return C.log10(a) +} + +// log_gamma computes the log-gamma function value +[inline] +pub fn log_gamma(a f64) f64 { + return C.lgamma(a) +} + +// log_n calculates base-N logarithm of the provided value. +[inline] +pub fn log_n(a, b f64) f64 { + return C.log(a) / C.log(b) +} + +// pow returns base raised to the provided power. +[inline] +pub fn pow(a, b f64) f64 { + return C.pow(a, b) +} + +// powf returns base raised to the provided power. (float32) +[inline] +pub fn powf(a, b f32) f32 { + return C.powf(a, b) +} + +// round returns the integer nearest to the provided value. +[inline] +pub fn round(f f64) f64 { + return C.round(f) +} + +// sin calculates sine. +[inline] +pub fn sin(a f64) f64 { + return C.sin(a) +} + +// sinf calculates sine. (float32) +[inline] +pub fn sinf(a f32) f32 { + return C.sinf(a) +} + +// sinh calculates hyperbolic sine. +[inline] +pub fn sinh(a f64) f64 { + return C.sinh(a) +} + +// sqrt calculates square-root of the provided value. +[inline] +pub fn sqrt(a f64) f64 { + return C.sqrt(a) +} + +// sqrtf calculates square-root of the provided value. (float32) +[inline] +pub fn sqrtf(a f32) f32 { + return C.sqrtf(a) +} + +// tan calculates tangent. +[inline] +pub fn tan(a f64) f64 { + return C.tan(a) +} + +// tanf calculates tangent. (float32) +[inline] +pub fn tanf(a f32) f32 { + return C.tanf(a) +} + +// tanh calculates hyperbolic tangent. +[inline] +pub fn tanh(a f64) f64 { + return C.tanh(a) +} + +// trunc rounds a toward zero, returning the nearest integral value that is not +// larger in magnitude than a. +[inline] +pub fn trunc(a f64) f64 { + return C.trunc(a) +} diff --git a/vlib/math/math.js.v b/vlib/math/math.js.v new file mode 100644 index 0000000000..0a2798de28 --- /dev/null +++ b/vlib/math/math.js.v @@ -0,0 +1,252 @@ +// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +module math + +// TODO : The commented out functions need either a native V implementation, a +// JS specific implementation, or use some other JS math library, such as +// https://github.com/josdejong/mathjs +fn JS.Math.abs(x f64) f64 // Replaces C.fabs +fn JS.Math.acos(x f64) f64 +fn JS.Math.asin(x f64) f64 +fn JS.Math.atan(x f64) f64 +fn JS.Math.atan2(y f64, x f64) f64 +fn JS.Math.cbrt(x f64) f64 +fn JS.Math.ceil(x f64) f64 +fn JS.Math.cos(x f64) f64 +fn JS.Math.cosh(x f64) f64 +//fn JS.Math.erf(x f64) f64 // Not in standard JS Math object +//fn JS.Math.erfc(x f64) f64 // Not in standard JS Math object +fn JS.Math.exp(x f64) f64 +//fn JS.Math.exp2(x f64) f64 // Not in standard JS Math object +fn JS.Math.floor(x f64) f64 +//fn JS.Math.fmod(x f64, y f64) f64 // Not in standard JS Math object +//fn JS.Math.hypot(x f64, y f64) f64 // Not in standard JS Math object +fn JS.Math.log(x f64) f64 +//fn JS.Math.log2(x f64) f64 // Not in standard JS Math object +//fn JS.Math.log10(x f64) f64 // Not in standard JS Math object +//fn JS.Math.lgamma(x f64) f64 // Not in standard JS Math object +fn JS.Math.pow(x f64, y f64) f64 +fn JS.Math.round(x f64) f64 +fn JS.Math.sin(x f64) f64 +fn JS.Math.sinh(x f64) f64 +fn JS.Math.sqrt(x f64) f64 +//fn JS.Math.tgamma(x f64) f64 // Not in standard JS Math object +fn JS.Math.tan(x f64) f64 +fn JS.Math.tanh(x f64) f64 +fn JS.Math.trunc(x f64) f64 + +// NOTE +// When adding a new function, please make sure it's in the right place. +// All functions are sorted alphabetically. + +// Returns the absolute value. +[inline] +pub fn abs(a f64) f64 { + return JS.Math.abs(a) +} + +// acos calculates inverse cosine (arccosine). +[inline] +pub fn acos(a f64) f64 { + return JS.Math.acos(a) +} + +// asin calculates inverse sine (arcsine). +[inline] +pub fn asin(a f64) f64 { + return JS.Math.asin(a) +} + +// atan calculates inverse tangent (arctangent). +[inline] +pub fn atan(a f64) f64 { + return JS.Math.atan(a) +} + +// atan2 calculates inverse tangent with two arguments, returns the angle between the X axis and the point. +[inline] +pub fn atan2(a, b f64) f64 { + return JS.Math.atan2(a, b) +} + +// cbrt calculates cubic root. +[inline] +pub fn cbrt(a f64) f64 { + return JS.Math.cbrt(a) +} + +// ceil returns the nearest f64 greater or equal to the provided value. +[inline] +pub fn ceil(a f64) f64 { + return JS.Math.ceil(a) +} + +// cos calculates cosine. +[inline] +pub fn cos(a f64) f64 { + return JS.Math.cos(a) +} + +// cosf calculates cosine. (float32). This doesn't exist in JS +[inline] +pub fn cosf(a f32) f32 { + return f32(JS.Math.cos(a)) +} + +// cosh calculates hyperbolic cosine. +[inline] +pub fn cosh(a f64) f64 { + return JS.Math.cosh(a) +} + +// exp calculates exponent of the number (math.pow(math.E, a)). +[inline] +pub fn exp(a f64) f64 { + return JS.Math.exp(a) +} + +// erf computes the error function value +[inline] +pub fn erf(a f64) f64 { + return JS.Math.erf(a) +} + +// erfc computes the complementary error function value +[inline] +pub fn erfc(a f64) f64 { + return JS.Math.erfc(a) +} + +// exp2 returns the base-2 exponential function of a (math.pow(2, a)). +[inline] +pub fn exp2(a f64) f64 { + return JS.Math.exp2(a) +} + +// floor returns the nearest f64 lower or equal of the provided value. +[inline] +pub fn floor(a f64) f64 { + return JS.Math.floor(a) +} + +// fmod returns the floating-point remainder of number / denom (rounded towards zero): +[inline] +pub fn fmod(a, b f64) f64 { + return JS.Math.fmod(a, b) +} + +// gamma computes the gamma function value +[inline] +pub fn gamma(a f64) f64 { + return JS.Math.tgamma(a) +} + +// Returns hypotenuse of a right triangle. +[inline] +pub fn hypot(a, b f64) f64 { + return JS.Math.hypot(a, b) +} + +// log calculates natural (base-e) logarithm of the provided value. +[inline] +pub fn log(a f64) f64 { + return JS.Math.log(a) +} + +// log2 calculates base-2 logarithm of the provided value. +[inline] +pub fn log2(a f64) f64 { + return JS.Math.log2(a) +} + +// log10 calculates the common (base-10) logarithm of the provided value. +[inline] +pub fn log10(a f64) f64 { + return JS.Math.log10(a) +} + +// log_gamma computes the log-gamma function value +[inline] +pub fn log_gamma(a f64) f64 { + return JS.Math.lgamma(a) +} + +// log_n calculates base-N logarithm of the provided value. +[inline] +pub fn log_n(a, b f64) f64 { + return JS.Math.log(a) / JS.Math.log(b) +} + +// pow returns base raised to the provided power. +[inline] +pub fn pow(a, b f64) f64 { + return JS.Math.pow(a, b) +} + +// powf returns base raised to the provided power. (float32) +[inline] +pub fn powf(a, b f32) f32 { + return f32(JS.Math.pow(a, b)) +} + +// round returns the integer nearest to the provided value. +[inline] +pub fn round(f f64) f64 { + return JS.Math.round(f) +} + +// sin calculates sine. +[inline] +pub fn sin(a f64) f64 { + return JS.Math.sin(a) +} + +// sinf calculates sine. (float32) +[inline] +pub fn sinf(a f32) f32 { + return f32(JS.Math.sin(a)) +} + +// sinh calculates hyperbolic sine. +[inline] +pub fn sinh(a f64) f64 { + return JS.Math.sinh(a) +} + +// sqrt calculates square-root of the provided value. +[inline] +pub fn sqrt(a f64) f64 { + return JS.Math.sqrt(a) +} + +// sqrtf calculates square-root of the provided value. (float32) +[inline] +pub fn sqrtf(a f32) f32 { + return f32(JS.Math.sqrt(a)) +} + +// tan calculates tangent. +[inline] +pub fn tan(a f64) f64 { + return JS.Math.tan(a) +} + +// tanf calculates tangent. (float32) +[inline] +pub fn tanf(a f32) f32 { + return f32(JS.Math.tan(a)) +} + +// tanh calculates hyperbolic tangent. +[inline] +pub fn tanh(a f64) f64 { + return JS.Math.tanh(a) +} + +// trunc rounds a toward zero, returning the nearest integral value that is not +// larger in magnitude than a. +[inline] +pub fn trunc(a f64) f64 { + return JS.Math.trunc(a) +} diff --git a/vlib/math/math.v b/vlib/math/math.v index ffd0099ddf..7779b21240 100644 --- a/vlib/math/math.v +++ b/vlib/math/math.v @@ -3,299 +3,15 @@ // that can be found in the LICENSE file. module math -#include - -fn C.acos(x f64) f64 -fn C.asin(x f64) f64 -fn C.atan(x f64) f64 -fn C.atan2(y f64, x f64) f64 -fn C.cbrt(x f64) f64 -fn C.ceil(x f64) f64 -fn C.cos(x f64) f64 -fn C.cosf(x f32) f32 -fn C.cosh(x f64) f64 -fn C.erf(x f64) f64 -fn C.erfc(x f64) f64 -fn C.exp(x f64) f64 -fn C.exp2(x f64) f64 -fn C.fabs(x f64) f64 -fn C.floor(x f64) f64 -fn C.fmod(x f64, y f64) f64 -fn C.hypot(x f64, y f64) f64 -fn C.log(x f64) f64 -fn C.log2(x f64) f64 -fn C.log10(x f64) f64 -fn C.lgamma(x f64) f64 -fn C.pow(x f64, y f64) f64 -fn C.powf(x f32, y f32) f32 -fn C.round(x f64) f64 -fn C.sin(x f64) f64 -fn C.sinf(x f32) f32 -fn C.sinh(x f64) f64 -fn C.sqrt(x f64) f64 -fn C.sqrtf(x f32) f32 -fn C.tgamma(x f64) f64 -fn C.tan(x f64) f64 -fn C.tanf(x f32) f32 -fn C.tanh(x f64) f64 -fn C.trunc(x f64) f64 - // NOTE // When adding a new function, please make sure it's in the right place. -// All functions are sorted alphabetically. +// All functions are sorted alphabetically, separated by wrapped functions vs +// backend specific functions. +// If using System/Backend dependent functions, put them in their respective +// .c.v or .js.v or other files -// Returns the absolute value. -pub fn abs(a f64) f64 { - return C.fabs(a) -} - -// acos calculates inverse cosine (arccosine). -pub fn acos(a f64) f64 { - return C.acos(a) -} - -// asin calculates inverse sine (arcsine). -pub fn asin(a f64) f64 { - return C.asin(a) -} - -// atan calculates inverse tangent (arctangent). -pub fn atan(a f64) f64 { - return C.atan(a) -} - -// atan2 calculates inverse tangent with two arguments, returns the angle between the X axis and the point. -pub fn atan2(a, b f64) f64 { - return C.atan2(a, b) -} - -// cbrt calculates cubic root. -pub fn cbrt(a f64) f64 { - return C.cbrt(a) -} - -// ceil returns the nearest f64 greater or equal to the provided value. -pub fn ceil(a f64) f64 { - return C.ceil(a) -} - -// cos calculates cosine. -pub fn cos(a f64) f64 { - return C.cos(a) -} - -// cosf calculates cosine. (float32) -pub fn cosf(a f32) f32 { - return C.cosf(a) -} - -// cosh calculates hyperbolic cosine. -pub fn cosh(a f64) f64 { - return C.cosh(a) -} - -// degrees convert from degrees to radians. -pub fn degrees(radians f64) f64 { - return radians * (180.0 / pi) -} - -// exp calculates exponent of the number (math.pow(math.E, a)). -pub fn exp(a f64) f64 { - return C.exp(a) -} - -// digits returns an array of the digits of n in the given base. -pub fn digits(_n, base int) []int { - if base < 2 { - panic('digits: Cannot find digits of n with base $base') - } - mut n := _n - mut sign := 1 - if n < 0 { - sign = -1 - n = -n - } - mut res := []int{} - for n != 0 { - res << (n % base) * sign - n /= base - } - return res -} - -// erf computes the error function value -pub fn erf(a f64) f64 { - return C.erf(a) -} - -// erfc computes the complementary error function value -pub fn erfc(a f64) f64 { - return C.erfc(a) -} - -// exp2 returns the base-2 exponential function of a (math.pow(2, a)). -pub fn exp2(a f64) f64 { - return C.exp2(a) -} - -// floor returns the nearest f64 lower or equal of the provided value. -pub fn floor(a f64) f64 { - return C.floor(a) -} - -// fmod returns the floating-point remainder of number / denom (rounded towards zero): -pub fn fmod(a, b f64) f64 { - return C.fmod(a, b) -} - -// gamma computes the gamma function value -pub fn gamma(a f64) f64 { - return C.tgamma(a) -} - -// gcd calculates greatest common (positive) divisor (or zero if a and b are both zero). -pub fn gcd(a_, b_ i64) i64 { - mut a := a_ - mut b := b_ - if a < 0 { - a = -a - } - if b < 0 { - b = -b - } - for b != 0 { - a %= b - if a == 0 { - return b - } - b %= a - } - return a -} - -// Returns hypotenuse of a right triangle. -pub fn hypot(a, b f64) f64 { - return C.hypot(a, b) -} - -// lcm calculates least common (non-negative) multiple. -pub fn lcm(a, b i64) i64 { - if a == 0 { - return a - } - res := a * (b / gcd(b, a)) - if res < 0 { - return -res - } - return res -} - -// log calculates natural (base-e) logarithm of the provided value. -pub fn log(a f64) f64 { - return C.log(a) -} - -// log2 calculates base-2 logarithm of the provided value. -pub fn log2(a f64) f64 { - return C.log2(a) -} - -// log10 calculates the common (base-10) logarithm of the provided value. -pub fn log10(a f64) f64 { - return C.log10(a) -} - -// log_gamma computes the log-gamma function value -pub fn log_gamma(a f64) f64 { - return C.lgamma(a) -} - -// log_n calculates base-N logarithm of the provided value. -pub fn log_n(a, b f64) f64 { - return C.log(a) / C.log(b) -} - -// max returns the maximum value of the two provided. -pub fn max(a, b f64) f64 { - if a > b { - return a - } - return b -} - -// min returns the minimum value of the two provided. -pub fn min(a, b f64) f64 { - if a < b { - return a - } - return b -} - -// pow returns base raised to the provided power. -pub fn pow(a, b f64) f64 { - return C.pow(a, b) -} - -// powf returns base raised to the provided power. (float32) -pub fn powf(a, b f32) f32 { - return C.powf(a, b) -} - -// radians convert from radians to degrees. -pub fn radians(degrees f64) f64 { - return degrees * (pi / 180.0) -} - -// round returns the integer nearest to the provided value. -pub fn round(f f64) f64 { - return C.round(f) -} - -// sin calculates sine. -pub fn sin(a f64) f64 { - return C.sin(a) -} - -// sinf calculates sine. (float32) -pub fn sinf(a f32) f32 { - return C.sinf(a) -} - -// sinh calculates hyperbolic sine. -pub fn sinh(a f64) f64 { - return C.sinh(a) -} - -// sqrt calculates square-root of the provided value. -pub fn sqrt(a f64) f64 { - return C.sqrt(a) -} - -// sqrtf calculates square-root of the provided value. (float32) -pub fn sqrtf(a f32) f32 { - return C.sqrtf(a) -} - -// tan calculates tangent. -pub fn tan(a f64) f64 { - return C.tan(a) -} - -// tanf calculates tangent. (float32) -pub fn tanf(a f32) f32 { - return C.tanf(a) -} - -// tanh calculates hyperbolic tangent. -pub fn tanh(a f64) f64 { - return C.tanh(a) -} - -// trunc rounds a toward zero, returning the nearest integral value that is not -// larger in magnitude than a. -pub fn trunc(a f64) f64 { - return C.trunc(a) -} +// Below are functions that are not wrappers for built-in system functions, but +// native V functions. They are still sorted alphabetically // Faster approximate sin() and cos() implemented from lolremez pub fn aprox_sin(a f64) f64 { @@ -327,3 +43,80 @@ pub fn aprox_cos(a f64) f64 { pub fn copysign(x, y f64) f64 { return f64_from_bits((f64_bits(x) & ~sign_mask) | (f64_bits(y) & sign_mask)) } + +// degrees convert from degrees to radians. +pub fn degrees(radians f64) f64 { + return radians * (180.0 / pi) +} + +// digits returns an array of the digits of n in the given base. +pub fn digits(_n, base int) []int { + if base < 2 { + panic('digits: Cannot find digits of n with base $base') + } + mut n := _n + mut sign := 1 + if n < 0 { + sign = -1 + n = -n + } + mut res := []int{} + for n != 0 { + res << (n % base) * sign + n /= base + } + return res +} + +// gcd calculates greatest common (positive) divisor (or zero if a and b are both zero). +pub fn gcd(a_, b_ i64) i64 { + mut a := a_ + mut b := b_ + if a < 0 { + a = -a + } + if b < 0 { + b = -b + } + for b != 0 { + a %= b + if a == 0 { + return b + } + b %= a + } + return a +} + +// lcm calculates least common (non-negative) multiple. +pub fn lcm(a, b i64) i64 { + if a == 0 { + return a + } + res := a * (b / gcd(b, a)) + if res < 0 { + return -res + } + return res +} + +// max returns the maximum value of the two provided. +pub fn max(a, b f64) f64 { + if a > b { + return a + } + return b +} + +// min returns the minimum value of the two provided. +pub fn min(a, b f64) f64 { + if a < b { + return a + } + return b +} + +// radians convert from radians to degrees. +pub fn radians(degrees f64) f64 { + return degrees * (pi / 180.0) +}