rust/fpnum/src/lib.rs
changeset 15837 42109eb6ef51
parent 15219 b71bae455926
child 15838 c910381d1ea9
equal deleted inserted replaced
15836:f7875779d910 15837:42109eb6ef51
   471 bin_assign_op_impl!(FPPoint, ops::SubAssign<FPNum>, sub_assign, -);
   471 bin_assign_op_impl!(FPPoint, ops::SubAssign<FPNum>, sub_assign, -);
   472 bin_assign_op_impl!(FPPoint, ops::MulAssign<FPNum>, mul_assign, *);
   472 bin_assign_op_impl!(FPPoint, ops::MulAssign<FPNum>, mul_assign, *);
   473 bin_assign_op_impl!(FPPoint, ops::DivAssign<FPNum>, div_assign, /);
   473 bin_assign_op_impl!(FPPoint, ops::DivAssign<FPNum>, div_assign, /);
   474 
   474 
   475 pub fn integral_sqrt(value: u64) -> u64 {
   475 pub fn integral_sqrt(value: u64) -> u64 {
   476     let mut digits = (64u32 - 1).saturating_sub(value.leading_zeros()) & 0xFFFF_FFFE;
   476     let mut digits = (64u32 - 1).saturating_sub(value.leading_zeros()) & 0xFE;
   477     let mut result = if value == 0 { 0u64 } else { 1u64 };
   477     let mut result = if value == 0 { 0u64 } else { 1u64 };
   478 
   478 
   479     while digits != 0 {
   479     while digits != 0 {
   480         result <<= 1;
   480         result <<= 1;
   481         if (result + 1).pow(2) <= value >> (digits - 2) {
   481         if (result + 1).pow(2) <= value >> (digits - 2) {
   486 
   486 
   487     result
   487     result
   488 }
   488 }
   489 
   489 
   490 pub fn integral_sqrt_ext(mut value: u128) -> u128 {
   490 pub fn integral_sqrt_ext(mut value: u128) -> u128 {
   491     let mut digit_sqr =
   491     let mut digits = (128u32 - 1).saturating_sub(value.leading_zeros()) & 0xFE;
   492         0x40000000_00000000_00000000_00000000u128.wrapping_shr(value.leading_zeros() & 0xFFFF_FFFE);
   492     let mut result = if value == 0 { 0u128 } else { 1u128 };
   493     let mut result = 0u128;
   493 
   494 
   494     while digits != 0 {
   495     while digit_sqr != 0 {
   495         result <<= 1;
   496         let approx = result + digit_sqr;
   496         if (result + 1).pow(2) <= value >> (digits - 2) {
   497         result >>= 1;
   497             result += 1;
   498 
   498         }
   499         if approx <= value {
   499         digits -= 2;
   500             value -= approx;
   500     }
   501             result += digit_sqr;
   501 
   502         }
       
   503         digit_sqr >>= 2;
       
   504     }
       
   505     result
   502     result
   506 }
   503 }
   507 
   504 
   508 #[inline]
   505 #[inline]
   509 pub fn distance<T>(x: T, y: T) -> FPNum
   506 pub fn distance<T>(x: T, y: T) -> FPNum