Skip to content

Instantly share code, notes, and snippets.

@timgluz
Created March 1, 2017 17:11
Show Gist options
  • Save timgluz/51a40affea66905f9dc957678c04a7a5 to your computer and use it in GitHub Desktop.
Save timgluz/51a40affea66905f9dc957678c04a7a5 to your computer and use it in GitHub Desktop.
Raise to float to any large power
// Calculate A to the power P.
Float: RaiseToPower(Float: A, Integer: P)
<Use the first fact to quickly calculate A, A2, A4, A8, and so on
until you get to a value AN where (N + 1 > P) >
<Use those powers of A and the second fact to calculate AP>
Return AP
End RaiseToPower
That's fewer multiplications than simply multiplying 7 × 7 × 7 × 7 × 7 × 7, but it's a small difference in this example.
Excerpt From: Stephens, Rod. “Essential Algorithms.” iBooks.
fn raise_to_power(a: f64, p: u32) -> f64 {
if p == 0 {return 1f64;}
let mut pows = VecDeque::new();
//step.1 calc A, A^2, A^4....
let mut a_curr = a;
let mut n = 1;
while n < p + 1 {
pows.push_back(a_curr.clone());
n = n * 2;
a_curr = a_curr * a_curr;
};
//step.2 calc power by using second rule A^{M+N} = A^M * A^N
n = pows.len() as u32;
let mut res = 1f64;
let mut filter_mask = (2u32.pow(n) - 1) & p;
while filter_mask > 0 {
let factor:f64 = pows.pop_front().unwrap();
if (filter_mask & 1) == 1 {
res *= factor;
}
filter_mask = filter_mask >> 1
}
res
}
#[test]
fn raise_to_power_test(){
assert_eq!(raise_to_power(7.0, 0), 1.0);
assert_eq!(raise_to_power(7.0, 1), 7.0);
assert_eq!(raise_to_power(7.0, 2), 49.0);
assert_eq!(raise_to_power(7.0, 3), 343.0);
assert_eq!(raise_to_power(7.0, 4), 2401.0);
assert_eq!(raise_to_power(7.0, 5), 16807.0);
assert_eq!(raise_to_power(7.0, 6), 117649.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment