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
max_i32 = 2147483647
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
// consecutive subtraction by 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
[inline]
pub fn copysign(x f64, y f64) f64 {
return f64_from_bits((f64_bits(x) & ~sign_mask) | (f64_bits(y) & sign_mask))
}
// degrees convert from degrees to radians.
[inline]
pub fn degrees(radians f64) f64 {
return radians * (180.0 / pi)
}
@ -59,6 +61,7 @@ pub fn digits(_n int, base int) []int {
return res
}
[inline]
pub fn fabs(x f64) f64 {
if x < 0.0 {
return -x
@ -99,6 +102,7 @@ pub fn lcm(a i64, b i64) i64 {
}
// max returns the maximum value of the two provided.
[inline]
pub fn max(a f64, b f64) f64 {
if a > b {
return a
@ -107,6 +111,7 @@ pub fn max(a f64, b f64) f64 {
}
// min returns the minimum value of the two provided.
[inline]
pub fn min(a f64, b f64) f64 {
if a < b {
return a
@ -114,12 +119,30 @@ pub fn min(a f64, b f64) f64 {
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.
[inline]
pub fn radians(degrees f64) f64 {
return degrees * (pi / 180.0)
}
// signbit returns a value with the boolean representation of the sign for x
[inline]
pub fn signbit(x f64) bool {
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() {
for i := 0; i < math.vf_.len; i++ {
f := exp(math.vf_[i])
@ -576,7 +619,7 @@ fn test_round() {
[f64(4503599627370495.5), 4503599627370496], /* 1 bit fraction, rounding to 0 bit fractian */
[f64(4503599627370497), 4503599627370497], /* large integer */
]
_ := vfround_even_sc_[0][0]
_ := vfround_even_sc_[0][0]
for i := 0; i < vfround_sc_.len; i++ {
f := round(vfround_sc_[i][0])
assert alike(vfround_sc_[i][1], f)