-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path083_pow_double.sio
More file actions
77 lines (59 loc) · 1.82 KB
/
083_pow_double.sio
File metadata and controls
77 lines (59 loc) · 1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//@ run-pass
// HumanEval 083: Power (Floating Point)
//
// Compute x^n for f64 base and i64 exponent using fast exponentiation
// (exponentiation by squaring). Handles negative exponents via 1/(x^|n|).
// O(log |n|) multiplications.
fn abs_i64(x: i64) -> i64 {
if x < 0 { 0 - x } else { x }
}
fn abs_f64(x: f64) -> f64 {
if x < 0.0 { 0.0 - x } else { x }
}
fn pow_double(x: f64, n: i64) -> f64 with Mut, Div, Panic {
if n == 0 { return 1.0 }
var base = x
var exp = abs_i64(n)
var result: f64 = 1.0
while exp > 0 {
if exp % 2 == 1 {
result = result * base
}
base = base * base
exp = exp / 2
}
if n < 0 {
1.0 / result
} else {
result
}
}
fn near(a: f64, b: f64, tol: f64) -> i64 {
let d = a - b
let ad = if d < 0.0 { 0.0 - d } else { d }
if ad < tol { 1 } else { 0 }
}
fn main() -> i64 with IO, Mut, Panic, Div {
// Test 1: 2.0^10 = 1024.0
assert(near(pow_double(2.0, 10), 1024.0, 0.001) == 1)
// Test 2: 2.0^0 = 1.0
assert(near(pow_double(2.0, 0), 1.0, 0.001) == 1)
// Test 3: 2.0^(-2) = 0.25
assert(near(pow_double(2.0, 0 - 2), 0.25, 0.001) == 1)
// Test 4: 3.0^3 = 27.0
assert(near(pow_double(3.0, 3), 27.0, 0.001) == 1)
// Test 5: 0.5^3 = 0.125
assert(near(pow_double(0.5, 3), 0.125, 0.001) == 1)
// Test 6: 1.0^1000 = 1.0
assert(near(pow_double(1.0, 1000), 1.0, 0.001) == 1)
// Test 7: 10.0^(-1) = 0.1
assert(near(pow_double(10.0, 0 - 1), 0.1, 0.001) == 1)
// Test 8: 5.0^1 = 5.0
assert(near(pow_double(5.0, 1), 5.0, 0.001) == 1)
// Test 9: 2.0^20 = 1048576.0
assert(near(pow_double(2.0, 20), 1048576.0, 0.1) == 1)
// Test 10: 0.0^5 = 0.0
assert(near(pow_double(0.0, 5), 0.0, 0.001) == 1)
println("083_pow_double: ALL TESTS PASSED")
0
}