mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
math: sqrti, powi, factoriali (#12072)
This commit is contained in:
parent
cd5b304cbf
commit
43931be451
@ -53,3 +53,16 @@ fn log_factorial_asymptotic_expansion(n int) f64 {
|
||||
}
|
||||
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(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)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// 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 {
|
||||
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
Block a user