2 * Utilities for signed modular arithmetic
3 * Author: Frank Pfenning
7 * There are two useful structure in the SML Basis Library
8 * Int32, with 2's complement arithmetic,
9 * but it raises Overflow instead of doing modular arithmetic
10 * Word32, with unsigned modular arithmetic
12 * This structure implements some signed operations on Word32
15 signature WORD32_SIGNED =
18 val TMAX : Word32.word (* largest signed positive word, 2^31-1 *)
19 val TMIN : Word32.word (* smallest signed negative word -2^31 *)
20 val ZERO : Word32.word (* 0 *)
21 val fromString : string -> Word32.word option (* parse from string, no sign *)
22 (* raises Overflow if not 0 <= n < 2^32 *)
23 val toString : Word32.word -> string (* print to string, with sign *)
24 val abs : Word32.word -> Word32.word
25 val adiv : Word32.word * Word32.word -> Word32.word
26 val amod : Word32.word * Word32.word -> Word32.word
27 val lt : Word32.word * Word32.word -> bool
28 val gt : Word32.word * Word32.word -> bool
29 val le : Word32.word * Word32.word -> bool
30 val ge : Word32.word * Word32.word -> bool
33 structure Word32Signed :> WORD32_SIGNED =
36 val TMIN = Word32.<<(Word32.fromInt(1), Word.fromInt(Word32.wordSize-1))
37 val TMAX = Word32.-(TMIN, Word32.fromInt(1))
38 val ZERO = Word32.fromInt(0)
39 fun neg w = Word32.>(w, TMAX)
41 (* fromString does not allow leading "-" *)
42 fun fromString (str) =
43 (* scanString might also raise Overflow *)
44 StringCvt.scanString (Word32.scan StringCvt.DEC) str
48 then "-0x" ^ Word32.fmt StringCvt.HEX (Word32.~(w))
49 else "0x" ^ Word32.fmt StringCvt.HEX w
51 fun toInt32 w = Int32.fromLarge (Word32.toLargeInt w)
52 fun fromInt32 i = Word32.fromLargeInt (Int32.toLarge i)
54 fun abs w = if neg w then Word32.~ (w) else w
55 fun adiv (a,b) = fromInt32 (Int32.div (toInt32 a, toInt32 b))
56 fun amod (a,b) = fromInt32 (Int32.mod (toInt32 a, if neg a andalso neg b then toInt32 b
57 else if neg b then toInt32 (abs b)
58 else if neg a then toInt32 (Word32.~ b)
61 fun lt (a,b) = Int32.compare (toInt32 a, toInt32 b) = LESS
62 fun gt (a,b) = Int32.compare (toInt32 a, toInt32 b) = GREATER
63 fun le (a,b) = case Int32.compare (toInt32 a, toInt32 b) of LESS => true | EQUAL => true | _ => false
64 fun ge (a,b) = case Int32.compare (toInt32 a, toInt32 b) of GREATER => true | EQUAL => true | _ => false