Skip to content

Commit a3fa575

Browse files
authored
math: speedup the pure V math.pow implementation for non-fractional powers (#19270)
1 parent 78659f4 commit a3fa575

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

vlib/math/ROADMAP.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
- [x] Move `vsl/vmath` to `vlib/math` as default backend
2-
- [ ] Implement `log` in pure V
3-
- [ ] Implement `pow` in pure V
2+
- [x] Implement `log` in pure V
3+
- [x] Implement `pow` in pure V
44
- [ ] Define functions for initial release of hardware implementations

vlib/math/math_test.v

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,8 @@ fn test_pow() {
776776
[pi, nan()], [inf(1), -pi], [inf(1), -0.0], [inf(1), 0],
777777
[inf(1), 1], [inf(1), pi], [inf(1), nan()], [nan(), -pi],
778778
[nan(), -0.0], [nan(), 0], [nan(), 1], [nan(), pi], [nan(),
779-
nan()]]
779+
nan()],
780+
[5.0, 2.0], [5.0, 3.0], [5.0, 10.0], [5.0, -2.0], [-5.0, -2.0]]
780781
pow_sc_ := [f64(0), // pow(-inf, -pi)
781782
-0.0, // pow(-inf, -3)
782783
1, // pow(-inf, -0)
@@ -839,6 +840,11 @@ fn test_pow() {
839840
nan(), // pow(nan, 1)
840841
nan(), // pow(nan, pi)
841842
nan(), // pow(nan, nan)
843+
25, // pow(5, 2) => 5 * 5
844+
125, // pow(5, 3) => 5 * 5 * 5
845+
9765625, // pow(5, 10)
846+
0.04, // pow(5, -2)
847+
-0.04, // pow(-5, -2)
842848
]
843849
for i := 0; i < vfpow_sc_.len; i++ {
844850
f := pow(vfpow_sc_[i][0], vfpow_sc_[i][1])

vlib/math/pow.v

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ pub fn pow(x f64, y f64) f64 {
8080
return x
8181
} else if is_nan(x) || is_nan(y) {
8282
return nan()
83+
} else if y == 2 {
84+
return x * x
85+
} else if y == 3 {
86+
return x * x * x
8387
} else if x == 0 {
8488
if y < 0 {
8589
if is_odd_int(y) {
@@ -133,6 +137,17 @@ pub fn pow(x f64, y f64) f64 {
133137
}
134138
}
135139

140+
if yf == 0.0 {
141+
mut result := x
142+
for _ in 1 .. i64(yi) {
143+
result *= x
144+
}
145+
if y > 0 {
146+
return result
147+
}
148+
return copysign(1, x) / abs(result)
149+
}
150+
136151
// ans = a1 * 2**ae (= 1 for now).
137152
mut a1 := 1.0
138153
mut ae := 0

0 commit comments

Comments
 (0)