-- Round to requested number of significant digits. If the number of
-- significant digits is greater than or equal to the place of the most
-- significant digit, move the decimal to the right the correct number of
-- places; round to an integer; then move it left. In the other case, move the
-- decimal to the left; round off; then move it right. Use the Rational type so
-- these rounded results come out exactly as rounded.
roundSigFig :: Int -> Float -> Rational
roundSigFig sigFigs x
  | k >= 0 = (round $ x * (10 ^ k)) R.% (10 ^ k)
  | k < 0  = (round $ x / (10.0 ^ (-k))) * (10 ^ (-k)) R.% 1
    where
      k = sigFigs - placeOfLeadingDigit
      placeOfLeadingDigit = (floor $ logBase 10 $ abs x) + 1
roundSigFig :: Int -> Float -> Rational
roundSigFig sigFigs x
  | k >= 0 = (round $ x * (10 ^ k)) R.% (10 ^ k)
  | k < 0  = (round $ x / (10.0 ^ (-k))) * (10 ^ (-k)) R.% 1
    where
      k = sigFigs - placeOfLeadingDigit
      placeOfLeadingDigit = (floor $ logBase 10 $ abs x) + 1
roundSigFig sigFigs x
  | k >= 0 = (round $ x * (10 ^ k)) R.% (10 ^ k)
  | k < 0  = (round $ x / (10.0 ^ (-k))) * (10 ^ (-k)) R.% 1
    where
      k = sigFigs - placeOfLeadingDigit
      placeOfLeadingDigit = (floor $ logBase 10 $ abs x) + 1