math: sign function (#10014)

pull/10038/head^2
Cabral 2021-05-08 08:32:18 -03:00 committed by GitHub
parent 68c8709343
commit b5afa049e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 2 deletions

View File

@ -37,7 +37,7 @@ pub const (
min_i16 = -32768 min_i16 = -32768
max_i32 = 2147483647 max_i32 = 2147483647
min_i32 = -2147483648 min_i32 = -2147483648
// -9223372036854775808 is wrong because C compilers parse litteral values // -9223372036854775808 is wrong because C compilers parse literal values
// without sign first, and 9223372036854775808 overflows i64, hence the // without sign first, and 9223372036854775808 overflows i64, hence the
// consecutive subtraction by 1 // consecutive subtraction by 1
min_i64 = i64(-9223372036854775807 - 1) min_i64 = i64(-9223372036854775807 - 1)

View File

@ -31,11 +31,13 @@ pub fn aprox_cos(a f64) f64 {
} }
// copysign returns a value with the magnitude of x and the sign of y // copysign returns a value with the magnitude of x and the sign of y
[inline]
pub fn copysign(x f64, y f64) f64 { pub fn copysign(x f64, y f64) f64 {
return f64_from_bits((f64_bits(x) & ~sign_mask) | (f64_bits(y) & sign_mask)) return f64_from_bits((f64_bits(x) & ~sign_mask) | (f64_bits(y) & sign_mask))
} }
// degrees convert from degrees to radians. // degrees convert from degrees to radians.
[inline]
pub fn degrees(radians f64) f64 { pub fn degrees(radians f64) f64 {
return radians * (180.0 / pi) return radians * (180.0 / pi)
} }
@ -59,6 +61,7 @@ pub fn digits(_n int, base int) []int {
return res return res
} }
[inline]
pub fn fabs(x f64) f64 { pub fn fabs(x f64) f64 {
if x < 0.0 { if x < 0.0 {
return -x return -x
@ -99,6 +102,7 @@ pub fn lcm(a i64, b i64) i64 {
} }
// max returns the maximum value of the two provided. // max returns the maximum value of the two provided.
[inline]
pub fn max(a f64, b f64) f64 { pub fn max(a f64, b f64) f64 {
if a > b { if a > b {
return a return a
@ -107,6 +111,7 @@ pub fn max(a f64, b f64) f64 {
} }
// min returns the minimum value of the two provided. // min returns the minimum value of the two provided.
[inline]
pub fn min(a f64, b f64) f64 { pub fn min(a f64, b f64) f64 {
if a < b { if a < b {
return a return a
@ -114,12 +119,30 @@ pub fn min(a f64, b f64) f64 {
return b return b
} }
// sign returns the corresponding sign -1.0, 1.0 of the provided number.
// if n is not a number, its sign is nan too.
[inline]
pub fn sign(n f64) f64 {
if is_nan(n) {
return nan()
}
return copysign(1.0, n)
}
// signi returns the corresponding sign -1.0, 1.0 of the provided number.
[inline]
pub fn signi(n f64) int {
return int(copysign(1.0, n))
}
// radians convert from radians to degrees. // radians convert from radians to degrees.
[inline]
pub fn radians(degrees f64) f64 { pub fn radians(degrees f64) f64 {
return degrees * (pi / 180.0) return degrees * (pi / 180.0)
} }
// signbit returns a value with the boolean representation of the sign for x // signbit returns a value with the boolean representation of the sign for x
[inline]
pub fn signbit(x f64) bool { pub fn signbit(x f64) bool {
return f64_bits(x) & sign_mask != 0 return f64_bits(x) & sign_mask != 0
} }

View File

@ -368,6 +368,49 @@ fn test_min() {
} }
} }
fn test_signi() {
assert signi(inf(-1)) == -1
assert signi(-72234878292.4586129) == -1
assert signi(-10) == -1
assert signi(-pi) == -1
assert signi(-1) == -1
assert signi(-0.000000000001) == -1
assert signi(-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001) == -1
assert signi(-0.0) == -1
//
assert signi(inf(1)) == 1
assert signi(72234878292.4586129) == 1
assert signi(10) == 1
assert signi(pi) == 1
assert signi(1) == 1
assert signi(0.000000000001) == 1
assert signi(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001) == 1
assert signi(0.0) == 1
assert signi(nan()) == 1
}
fn test_sign() {
assert sign(inf(-1)) == -1.0
assert sign(-72234878292.4586129) == -1.0
assert sign(-10) == -1.0
assert sign(-pi) == -1.0
assert sign(-1) == -1.0
assert sign(-0.000000000001) == -1.0
assert sign(-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001) == -1.0
assert sign(-0.0) == -1.0
//
assert sign(inf(1)) == 1.0
assert sign(72234878292.4586129) == 1
assert sign(10) == 1.0
assert sign(pi) == 1.0
assert sign(1) == 1.0
assert sign(0.000000000001) == 1.0
assert sign(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001) == 1.0
assert sign(0.0) == 1.0
assert is_nan(sign(nan()))
assert is_nan(sign(-nan()))
}
fn test_exp() { fn test_exp() {
for i := 0; i < math.vf_.len; i++ { for i := 0; i < math.vf_.len; i++ {
f := exp(math.vf_[i]) f := exp(math.vf_[i])