math: sqrti, powi, factoriali (#12072)
parent
cd5b304cbf
commit
43931be451
|
@ -53,3 +53,16 @@ fn log_factorial_asymptotic_expansion(n int) f64 {
|
||||||
}
|
}
|
||||||
return log_factorial + sum
|
return log_factorial + sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// factoriali returns 1 for n <= 0 and -1 if the result is too large for a 64 bit integer
|
||||||
|
pub fn factoriali(n int) i64 {
|
||||||
|
if n <= 0 {
|
||||||
|
return i64(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n < 21 {
|
||||||
|
return i64(factorials_table[n])
|
||||||
|
}
|
||||||
|
|
||||||
|
return i64(-1)
|
||||||
|
}
|
||||||
|
|
|
@ -11,3 +11,12 @@ fn test_log_factorial() {
|
||||||
assert log_factorial(5) == log(120)
|
assert log_factorial(5) == log(120)
|
||||||
assert log_factorial(0) == log(1)
|
assert log_factorial(0) == log(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_factoriali() {
|
||||||
|
assert factoriali(20) == 2432902008176640000
|
||||||
|
assert factoriali(1) == 1
|
||||||
|
assert factoriali(2) == 2
|
||||||
|
assert factoriali(0) == 1
|
||||||
|
assert factoriali(-2) == 1
|
||||||
|
assert factoriali(1000) == -1
|
||||||
|
}
|
||||||
|
|
|
@ -946,3 +946,15 @@ fn test_large_tan() {
|
||||||
assert soclose(f1, f2, 4e-8)
|
assert soclose(f1, f2, 4e-8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_sqrti() {
|
||||||
|
assert sqrti(i64(123456789) * i64(123456789)) == 123456789
|
||||||
|
assert sqrti(144) == 12
|
||||||
|
assert sqrti(0) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_powi() {
|
||||||
|
assert powi(2, 62) == i64(4611686018427387904)
|
||||||
|
assert powi(0, -2) == -1 // div by 0
|
||||||
|
assert powi(2, -1) == 0
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,41 @@ pub fn pow10(n int) f64 {
|
||||||
return 0.0
|
return 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// powi returns base raised to power (a**b) as an integer (i64)
|
||||||
|
//
|
||||||
|
// special case:
|
||||||
|
// powi(a, b) = -1 for a = 0 and b < 0
|
||||||
|
pub fn powi(a i64, b i64) i64 {
|
||||||
|
mut b_ := b
|
||||||
|
mut p := a
|
||||||
|
mut v := i64(1)
|
||||||
|
|
||||||
|
if b_ < 0 { // exponent < 0
|
||||||
|
if a == 0 {
|
||||||
|
return -1 // division by 0
|
||||||
|
}
|
||||||
|
return if a * a != 1 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
if (b_ & 1) > 0 {
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ; b_ > 0; {
|
||||||
|
if b_ & 1 > 0 {
|
||||||
|
v *= p
|
||||||
|
}
|
||||||
|
p *= p
|
||||||
|
b_ >>= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
// pow returns base raised to the provided power.
|
// pow returns base raised to the provided power.
|
||||||
//
|
//
|
||||||
// todo(playXE): make this function work on JS backend, probably problem of JS codegen that it does not work.
|
// todo(playXE): make this function work on JS backend, probably problem of JS codegen that it does not work.
|
||||||
|
|
|
@ -35,3 +35,22 @@ pub fn sqrt(a f64) f64 {
|
||||||
pub fn sqrtf(a f32) f32 {
|
pub fn sqrtf(a f32) f32 {
|
||||||
return f32(sqrt(a))
|
return f32(sqrt(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sqrti calculates the integer square-root of the provided value. (i64)
|
||||||
|
pub fn sqrti(a i64) i64 {
|
||||||
|
mut x := a
|
||||||
|
mut q, mut r := i64(1), i64(0)
|
||||||
|
for ; q <= x; {
|
||||||
|
q <<= 2
|
||||||
|
}
|
||||||
|
for ; q > 1; {
|
||||||
|
q >>= 2
|
||||||
|
t := x - r - q
|
||||||
|
r >>= 1
|
||||||
|
if t >= 0 {
|
||||||
|
x = t
|
||||||
|
r += q
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue