2016-07-30 3 views
0

저는 녹에서 효율적인 제곱 법을 쓰고 있습니다. AbstractNumberMul 특성이 블랙 박스이고 우리가 안전하고 관용적 인 녹이 허용된다고 가정합시다.녹에 효율적인 전력 함수 작성

다음은 더 큰 인덱스에 대해 반복 제곱을 사용하는 첫 번째 단계입니다. LLVM이 checked_next_power_of_two()과 같은 Rust 산술 방식 호출을 어떻게 변환하는지 확신 할 수 없습니다.

다음과 같이 보입니까? 소문자 분기를 자체 인라인 함수로 분리하는 것이 더 효율적입니까?

/// Compute an integer power of this number efficiently with repeated squaring. 
pub fn pow(&self, n: u32) -> AbstractNumber { 
    let optimization = 5; 

    if n < optimization { 
     let mut x = Complex::one(); 

     for _ in 0..n { 
      x *= *self; 
     } 

     x 
    } else { 
     // l = floor(log_2(n)), r = n - 2^l 
     let (l, r) = if n.is_power_of_two() { 
      (n.trailing_zeros(), 0) 
     } else { 
      let p = n.checked_next_power_of_two().unwrap().trailing_zeros() - 1; 
      (p, n - 2u32.pow(p)) 
     }; 

     let mut x = *self; 

     for _ in 0..l { 
      x *= x; 
     } 

     self.pow(r) * x 
    } 
} 

답변

3

num::pow::pow를 사용할 수 있습니까? 어떤 경우에는, 여기가 구현되는 방법입니다 :

#[inline] 
pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T { 
    if exp == 0 { return T::one() } 

    while exp & 1 == 0 { 
     base = base.clone() * base; 
     exp >>= 1; 
    } 
    if exp == 1 { return base } 

    let mut acc = base.clone(); 
    while exp > 1 { 
     exp >>= 1; 
     base = base.clone() * base; 
     if exp & 1 == 1 { 
      acc = acc * base.clone(); 
     } 
    } 
    acc 
} 

Mul에 추가 Clone 필요 (그리고 One을하지만 일반적인 것을하지 않는 경우 즉, 필요하지 않은 것).

그런데 Rust에서 비트 연산을 사용하는 데있어 아무 문제가 없거나 안전하지 않습니다.

+0

감사합니다. 사용하겠습니다. –