implementation module fixed /* Numbers with 5 decimal precision Pieter Koopman, 2010 Radboud Universty, Nijmegen The Netherlands pieter@cs.ru.nl */ import StdEnv, BigInt :: Fixed = Fixed !BigInt instance toString Fixed where toString (Fixed bi) = (if (bi String toStringFixed n string 0 = string toStringFixed 0 string remainder = string toStringFixed n string remainder = toStringFixed (n-1) {string & [n] = '0'+toChar (remainder rem 10)} (remainder/10) class toFixed a :: a -> Fixed instance toFixed Int where toFixed i = Fixed (FACTOR * (toBigInt i)) instance toFixed BigInt where toFixed bi = Fixed (FACTOR * bi) instance toFixed String where toFixed s = stringToFixed zero 0 (size s-1) s stringToFixed :: !BigInt !Int !Int !String -> Fixed stringToFixed b i l s | i>l // end string = toFixed b | s.[i] == '.' = fracToFixed b 5 (i+1) l s | isDigit s.[i] = stringToFixed ((b*%10)+%(toInt(s.[i]-'0'))) (i+1) l s = toFixed b fracToFixed b n i l s | i>l || n<0 = Fixed (b*%(10^n)) | isDigit s.[i] = fracToFixed ((b*%10)+%(toInt(s.[i]-'0'))) (n-1) (i+1) l s = Fixed (b*%(10^n)) instance == Fixed where (==) (Fixed x) (Fixed y) = x == y instance < Fixed where (<) (Fixed x) (Fixed y) = x < y // Arithmetic: instance + Fixed where (+) (Fixed x) (Fixed y) = Fixed (x + y) instance - Fixed where (-) (Fixed x) (Fixed y) = Fixed (x - y) instance zero Fixed where zero = Fixed zero instance * Fixed where (*) (Fixed x) (Fixed y) = Fixed ((x * y)/FACTOR) instance / Fixed where (/) (Fixed x) (Fixed y) = Fixed ((FACTOR * x) / y) // Truncated to 0 instance one Fixed where one = Fixed (FACTOR * one) instance abs Fixed where abs (Fixed x) = Fixed (abs x) instance ~ Fixed where ~ (Fixed x) = Fixed (~ x) instance mod Fixed where (mod) (Fixed x) (Fixed y) = Fixed (FACTOR * (x mod y)) instance rem Fixed where (rem) (Fixed x) (Fixed y) = Fixed (FACTOR * (x rem y)) instance toInt Fixed where toInt (Fixed x) = toInt (x/FACTOR) FACTOR :: BigInt FACTOR =: toBigInt (10^PRECISION) PRECISION :: Int PRECISION =: 5 INCPRECISION :: Int INCPRECISION =: PRECISION+1