-- | -- = 第3章 練習問題 E -- -- * @isqrt :: Float -> Integer@ は非負数の平方根の床を返す関数である. -- 3.3 節の戦略に従って,@isqrt x@ を log x ステップで計算する実装を構成せよ. -- -- @ -- isqrt :: Float -> Integer -- isqrt x = fst (until unit (shrink x) (bound x)) -- where -- unit (m,n) = m + 1 == n -- -- shrink :: Float -> Interval -> Interval -- shrink x (m, n) = if (p * p) `leq` x then (p, n) else (m, p) -- where -- p = (m + n) `div` 2 -- -- bound :: Float -> Interval -- bound x = (0, until above (* 2) 1) -- where -- above n = x `lt` (n * n) -- @ module TFwH.Chap03.ExE where type Interval = (Integer, Integer) -- | -- 非負数の平方根の床を返す -- -- >>> isqrt 123456.78 -- 351 -- isqrt :: Float -> Integer isqrt x = fst (until unit (shrink x) (bound x)) where unit (m,n) = m + 1 == n -- | -- 区間の縮小 -- shrink :: Float -> Interval -> Interval shrink x (m, n) = if (p * p) `leq` x then (p, n) else (m, p) where p = (m + n) `div` 2 -- | -- 最初の区間 bound :: Float -> Interval bound x = (0, until above (* 2) 1) where above n = x `lt` (n * n) -- | -- ≦ -- leq :: Integer -> Float -> Bool m `leq` x = fromIntegral m <= x -- | -- < -- lt :: Float -> Integer -> Bool x `lt` n = x < fromIntegral n