diff --git a/fractional/src/fractional.rs b/fractional/src/fractional.rs index 27ce83a..387f907 100644 --- a/fractional/src/fractional.rs +++ b/fractional/src/fractional.rs @@ -62,6 +62,33 @@ impl Fractional { pub fn denominator(self) -> i64 { self.1 } + + pub fn sqrt(self) -> Self { + // find the sqrt of x in O(log x/2). + fn floor_sqrt(x :i64) -> i64 { + fn inner(l :i64, h :i64, x :i64) -> i64 { + if l > h { + l - 1 + } else { + let m = (l + h) / 2; + match x.cmp(&(m * m)) { + Ordering::Equal => m, + Ordering::Less => inner(l, m, x), + Ordering::Greater => inner(m + 1, h, x), + } + } + } + + match x.cmp(&0) { + Ordering::Equal => 0, + Ordering::Less => -inner(1, -x / 2, -x), + Ordering::Greater => inner(1, x / 2, x), + } + } + + let Fractional(n, d) = self; + Fractional(floor_sqrt(n), floor_sqrt(d)).reduce() + } } impl fmt::Display for Fractional { diff --git a/fractional/src/main.rs b/fractional/src/main.rs index a4e6d23..4539b93 100644 --- a/fractional/src/main.rs +++ b/fractional/src/main.rs @@ -45,12 +45,19 @@ fn main() { let d :f64 = c.try_into().unwrap(); let e :f64 = Fractional::try_into(c).unwrap(); + let f = Fractional(9, 4); + let g = Fractional(-9, 4); + println!(" [i32] : {:?}" , a); println!(" [Fractional] : {:?}" , b); println!(" mean of [i32] : {}" , c); println!(" as f64 : {}" , d); println!(" and as f64 : {}" , e); println!(" again as f64 : {}" , TryInto::::try_into(c).unwrap()); + println!(" sqrt f : {}" , f.sqrt()); + println!(" sqrt f as f64 : {}" , TryInto::::try_into(f.sqrt()).unwrap()); + println!(" sqrt g : {}" , g.sqrt()); + println!(" sqrt g as f64 : {}" , TryInto::::try_into(g.sqrt()).unwrap()); println!(" Rust π : {}" , FPI); println!(" π : {} {}" , TryInto::::try_into(PI).unwrap(), PI); println!(" π as tuple : {:?}" , TryInto::<(i32, i32)>::try_into(PI).unwrap());