fix powi
This commit is contained in:
@@ -15,6 +15,7 @@ pub mod sub;
|
||||
#[doc(hidden)]
|
||||
pub trait Float:
|
||||
Copy
|
||||
+ core::fmt::Debug
|
||||
+ PartialEq
|
||||
+ PartialOrd
|
||||
+ ops::AddAssign
|
||||
|
||||
@@ -1,39 +1,36 @@
|
||||
use float::Float;
|
||||
use int::Int;
|
||||
|
||||
trait Pow: Float {
|
||||
/// Returns `a` raised to the power `b`
|
||||
fn pow(self, mut b: i32) -> Self {
|
||||
let mut a = self;
|
||||
let recip = b < 0;
|
||||
let mut r = Self::ONE;
|
||||
loop {
|
||||
if (b & 1) != 0 {
|
||||
r *= a;
|
||||
}
|
||||
b = ((b as u32) >> 1) as i32;
|
||||
if b == 0 {
|
||||
break;
|
||||
}
|
||||
a *= a;
|
||||
/// Returns `a` raised to the power `b`
|
||||
fn pow<F: Float>(a: F, b: i32) -> F {
|
||||
let mut a = a;
|
||||
let recip = b < 0;
|
||||
let mut pow = i32::abs_diff(b, 0);
|
||||
let mut mul = F::ONE;
|
||||
loop {
|
||||
if (pow & 1) != 0 {
|
||||
mul *= a;
|
||||
}
|
||||
pow >>= 1;
|
||||
if pow == 0 {
|
||||
break;
|
||||
}
|
||||
a *= a;
|
||||
}
|
||||
|
||||
if recip {
|
||||
Self::ONE / r
|
||||
} else {
|
||||
r
|
||||
}
|
||||
if recip {
|
||||
F::ONE / mul
|
||||
} else {
|
||||
mul
|
||||
}
|
||||
}
|
||||
|
||||
impl Pow for f32 {}
|
||||
impl Pow for f64 {}
|
||||
|
||||
intrinsics! {
|
||||
pub extern "C" fn __powisf2(a: f32, b: i32) -> f32 {
|
||||
a.pow(b)
|
||||
pow(a, b)
|
||||
}
|
||||
|
||||
pub extern "C" fn __powidf2(a: f64, b: i32) -> f64 {
|
||||
a.pow(b)
|
||||
pow(a, b)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user