Update with wrapping ops

Closes #21
diff --git a/Cargo.toml b/Cargo.toml
index 7bc04b6..c27e052 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 
 name = "rand"
-version = "0.1.3"
+version = "0.1.4"
 authors = ["The Rust Project Developers"]
 license = "MIT/Apache-2.0"
 readme = "README.md"
diff --git a/src/chacha.rs b/src/chacha.rs
index 526e895..36543e8 100644
--- a/src/chacha.rs
+++ b/src/chacha.rs
@@ -11,8 +11,10 @@
 //! The ChaCha random number generator.
 
 use core::prelude::*;
+
 use core::num::Int;
-use {Rng, SeedableRng, Rand};
+use core::num::wrapping::Wrapping as w;
+use {Rng, SeedableRng, Rand, w32};
 
 const KEY_WORDS    : usize =  8; // 8 words for the 256-bit key
 const STATE_WORDS  : usize = 16;
@@ -29,24 +31,24 @@
 /// Salsa20*](http://cr.yp.to/chacha.html)
 #[derive(Copy, Clone)]
 pub struct ChaChaRng {
-    buffer:  [u32; STATE_WORDS], // Internal buffer of output
-    state:   [u32; STATE_WORDS], // Initial state
+    buffer:  [w32; STATE_WORDS], // Internal buffer of output
+    state:   [w32; STATE_WORDS], // Initial state
     index:   usize,                 // Index into state
 }
 
 static EMPTY: ChaChaRng = ChaChaRng {
-    buffer:  [0; STATE_WORDS],
-    state:   [0; STATE_WORDS],
+    buffer:  [w(0); STATE_WORDS],
+    state:   [w(0); STATE_WORDS],
     index:   STATE_WORDS
 };
 
 
 macro_rules! quarter_round{
     ($a: expr, $b: expr, $c: expr, $d: expr) => {{
-        $a += $b; $d ^= $a; $d = $d.rotate_left(16);
-        $c += $d; $b ^= $c; $b = $b.rotate_left(12);
-        $a += $b; $d ^= $a; $d = $d.rotate_left( 8);
-        $c += $d; $b ^= $c; $b = $b.rotate_left( 7);
+        $a = $a + $b; $d = $d ^ $a; $d = w($d.0.rotate_left(16));
+        $c = $c + $d; $b = $b ^ $c; $b = w($b.0.rotate_left(12));
+        $a = $a + $b; $d = $d ^ $a; $d = w($d.0.rotate_left( 8));
+        $c = $c + $d; $b = $b ^ $c; $b = w($b.0.rotate_left( 7));
     }}
 }
 
@@ -66,7 +68,7 @@
 }
 
 #[inline]
-fn core(output: &mut [u32; STATE_WORDS], input: &[u32; STATE_WORDS]) {
+fn core(output: &mut [w32; STATE_WORDS], input: &[w32; STATE_WORDS]) {
     *output = *input;
 
     for _ in 0..CHACHA_ROUNDS / 2 {
@@ -74,7 +76,7 @@
     }
 
     for i in 0..STATE_WORDS {
-        output[i] += input[i];
+        output[i] = output[i] + input[i];
     }
 }
 
@@ -97,10 +99,10 @@
     /// associated with a particular nonce can call this function with
     /// arguments `0, desired_nonce`.
     pub fn set_counter(&mut self, counter_low: u64, counter_high: u64) {
-        self.state[12] = (counter_low >>  0) as u32;
-        self.state[13] = (counter_low >> 32) as u32;
-        self.state[14] = (counter_high >>  0) as u32;
-        self.state[15] = (counter_high >> 32) as u32;
+        self.state[12] = w((counter_low >>  0) as u32);
+        self.state[13] = w((counter_low >> 32) as u32);
+        self.state[14] = w((counter_high >>  0) as u32);
+        self.state[15] = w((counter_high >> 32) as u32);
         self.index = STATE_WORDS; // force recomputation
     }
 
@@ -123,19 +125,19 @@
     /// [1]: Daniel J. Bernstein. [*Extending the Salsa20
     /// nonce.*](http://cr.yp.to/papers.html#xsalsa)
     fn init(&mut self, key: &[u32; KEY_WORDS]) {
-        self.state[0] = 0x61707865;
-        self.state[1] = 0x3320646E;
-        self.state[2] = 0x79622D32;
-        self.state[3] = 0x6B206574;
+        self.state[0] = w(0x61707865);
+        self.state[1] = w(0x3320646E);
+        self.state[2] = w(0x79622D32);
+        self.state[3] = w(0x6B206574);
 
         for i in 0..KEY_WORDS {
-            self.state[4+i] = key[i];
+            self.state[4+i] = w(key[i]);
         }
 
-        self.state[12] = 0;
-        self.state[13] = 0;
-        self.state[14] = 0;
-        self.state[15] = 0;
+        self.state[12] = w(0);
+        self.state[13] = w(0);
+        self.state[14] = w(0);
+        self.state[15] = w(0);
 
         self.index = STATE_WORDS;
     }
@@ -145,13 +147,13 @@
         core(&mut self.buffer, &self.state);
         self.index = 0;
         // update 128-bit counter
-        self.state[12] += 1;
-        if self.state[12] != 0 { return };
-        self.state[13] += 1;
-        if self.state[13] != 0 { return };
-        self.state[14] += 1;
-        if self.state[14] != 0 { return };
-        self.state[15] += 1;
+        self.state[12] = self.state[12] + w(1);
+        if self.state[12] != w(0) { return };
+        self.state[13] = self.state[13] + w(1);
+        if self.state[13] != w(0) { return };
+        self.state[14] = self.state[14] + w(1);
+        if self.state[14] != w(0) { return };
+        self.state[15] = self.state[15] + w(1);
     }
 }
 
@@ -164,7 +166,7 @@
 
         let value = self.buffer[self.index % STATE_WORDS];
         self.index += 1;
-        value
+        value.0
     }
 }
 
@@ -176,7 +178,7 @@
         // set key in place
         let key = &mut self.state[4 .. 4+KEY_WORDS];
         for (k, s) in key.iter_mut().zip(seed.iter()) {
-            *k = *s;
+            *k = w(*s);
         }
     }
 
diff --git a/src/distributions/range.rs b/src/distributions/range.rs
index 29d8fe6..e74ace1 100644
--- a/src/distributions/range.rs
+++ b/src/distributions/range.rs
@@ -14,6 +14,7 @@
 
 use core::prelude::{PartialOrd};
 use core::num::Int;
+use core::num::wrapping::Wrapping as w;
 
 use Rng;
 use distributions::{Sample, IndependentSample};
@@ -97,7 +98,7 @@
             // bijection.
 
             fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
-                let range = high as $unsigned - low as $unsigned;
+                let range = (w(high as $unsigned) - w(low as $unsigned)).0;
                 let unsigned_max: $unsigned = Int::max_value();
 
                 // this is the largest number that fits into $unsigned
@@ -122,7 +123,7 @@
                     // be uniformly distributed)
                     if v < r.accept_zone as $unsigned {
                         // and return it, with some adjustments
-                        return r.low + (v % r.range as $unsigned) as $ty;
+                        return (w(r.low) + w((v % r.range as $unsigned) as $ty)).0;
                     }
                 }
             }
diff --git a/src/isaac.rs b/src/isaac.rs
index f07428d..9c77c8b 100644
--- a/src/isaac.rs
+++ b/src/isaac.rs
@@ -10,13 +10,16 @@
 
 //! The ISAAC random number generator.
 
+#![allow(non_camel_case_types)]
+
 use core::prelude::*;
 use core::slice;
 use core::iter::{range_step, repeat};
+use core::num::wrapping::Wrapping as w;
 
-use {Rng, SeedableRng, Rand};
+use {Rng, SeedableRng, Rand, w32, w64};
 
-const RAND_SIZE_LEN: u32 = 8;
+const RAND_SIZE_LEN: usize = 8;
 const RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
 const RAND_SIZE_USIZE: usize = 1 << RAND_SIZE_LEN;
 
@@ -32,18 +35,18 @@
 #[derive(Copy)]
 pub struct IsaacRng {
     cnt: u32,
-    rsl: [u32; RAND_SIZE_USIZE],
-    mem: [u32; RAND_SIZE_USIZE],
-    a: u32,
-    b: u32,
-    c: u32
+    rsl: [w32; RAND_SIZE_USIZE],
+    mem: [w32; RAND_SIZE_USIZE],
+    a: w32,
+    b: w32,
+    c: w32,
 }
 
 static EMPTY: IsaacRng = IsaacRng {
     cnt: 0,
-    rsl: [0; RAND_SIZE_USIZE],
-    mem: [0; RAND_SIZE_USIZE],
-    a: 0, b: 0, c: 0
+    rsl: [w(0); RAND_SIZE_USIZE],
+    mem: [w(0); RAND_SIZE_USIZE],
+    a: w(0), b: w(0), c: w(0),
 };
 
 impl IsaacRng {
@@ -60,7 +63,7 @@
     /// of `rsl` as a seed, otherwise construct one algorithmically (not
     /// randomly).
     fn init(&mut self, use_rsl: bool) {
-        let mut a = 0x9e3779b9;
+        let mut a = w(0x9e3779b9);
         let mut b = a;
         let mut c = a;
         let mut d = a;
@@ -71,14 +74,14 @@
 
         macro_rules! mix {
             () => {{
-                a^=b<<11; d+=a; b+=c;
-                b^=c>>2;  e+=b; c+=d;
-                c^=d<<8;  f+=c; d+=e;
-                d^=e>>16; g+=d; e+=f;
-                e^=f<<10; h+=e; f+=g;
-                f^=g>>4;  a+=f; g+=h;
-                g^=h<<8;  b+=g; h+=a;
-                h^=a>>9;  c+=h; a+=b;
+                a=a^(b<<11); d=d+a; b=b+c;
+                b=b^(c>>2);  e=e+b; c=c+d;
+                c=c^(d<<8);  f=f+c; d=d+e;
+                d=d^(e>>16); g=g+d; e=e+f;
+                e=e^(f<<10); h=h+e; f=f+g;
+                f=f^(g>>4);  a=a+f; g=g+h;
+                g=g^(h<<8);  b=b+g; h=h+a;
+                h=h^(a>>9);  c=c+h; a=a+b;
             }}
         }
 
@@ -90,10 +93,10 @@
             macro_rules! memloop {
                 ($arr:expr) => {{
                     for i in range_step(0, RAND_SIZE_USIZE, 8) {
-                        a+=$arr[i  ]; b+=$arr[i+1];
-                        c+=$arr[i+2]; d+=$arr[i+3];
-                        e+=$arr[i+4]; f+=$arr[i+5];
-                        g+=$arr[i+6]; h+=$arr[i+7];
+                        a=a+$arr[i  ]; b=b+$arr[i+1];
+                        c=c+$arr[i+2]; d=d+$arr[i+3];
+                        e=e+$arr[i+4]; f=f+$arr[i+5];
+                        g=g+$arr[i+6]; h=h+$arr[i+7];
                         mix!();
                         self.mem[i  ]=a; self.mem[i+1]=b;
                         self.mem[i+2]=c; self.mem[i+3]=d;
@@ -122,15 +125,15 @@
     #[inline]
     #[allow(unsigned_negation)]
     fn isaac(&mut self) {
-        self.c += 1;
+        self.c = self.c + w(1);
         // abbreviations
         let mut a = self.a;
         let mut b = self.b + self.c;
 
-        static MIDPOINT: usize = RAND_SIZE_USIZE / 2;
+        const MIDPOINT: usize = RAND_SIZE_USIZE / 2;
 
         macro_rules! ind {
-            ($x:expr) => ( self.mem[($x >> 2) as usize & (RAND_SIZE_USIZE - 1)] )
+            ($x:expr) => ( self.mem[($x >> 2).0 as usize & (RAND_SIZE_USIZE - 1)] )
         }
 
         let r = [(0, MIDPOINT), (MIDPOINT, 0)];
@@ -207,7 +210,7 @@
         // (the % is cheaply telling the optimiser that we're always
         // in bounds, without unsafe. NB. this is a power of two, so
         // it optimises to a bitwise mask).
-        self.rsl[(self.cnt % RAND_SIZE) as usize]
+        self.rsl[(self.cnt % RAND_SIZE) as usize].0
     }
 }
 
@@ -218,12 +221,12 @@
         let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u32));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
-            *rsl_elem = seed_elem;
+            *rsl_elem = w(seed_elem);
         }
         self.cnt = 0;
-        self.a = 0;
-        self.b = 0;
-        self.c = 0;
+        self.a = w(0);
+        self.b = w(0);
+        self.c = w(0);
 
         self.init(true);
     }
@@ -250,9 +253,9 @@
             other.fill_bytes(slice);
         }
         ret.cnt = 0;
-        ret.a = 0;
-        ret.b = 0;
-        ret.c = 0;
+        ret.a = w(0);
+        ret.b = w(0);
+        ret.c = w(0);
 
         ret.init(true);
         return ret;
@@ -275,18 +278,18 @@
 #[derive(Copy)]
 pub struct Isaac64Rng {
     cnt: usize,
-    rsl: [u64; RAND_SIZE_64],
-    mem: [u64; RAND_SIZE_64],
-    a: u64,
-    b: u64,
-    c: u64,
+    rsl: [w64; RAND_SIZE_64],
+    mem: [w64; RAND_SIZE_64],
+    a: w64,
+    b: w64,
+    c: w64,
 }
 
 static EMPTY_64: Isaac64Rng = Isaac64Rng {
     cnt: 0,
-    rsl: [0; RAND_SIZE_64],
-    mem: [0; RAND_SIZE_64],
-    a: 0, b: 0, c: 0,
+    rsl: [w(0); RAND_SIZE_64],
+    mem: [w(0); RAND_SIZE_64],
+    a: w(0), b: w(0), c: w(0),
 };
 
 impl Isaac64Rng {
@@ -304,7 +307,7 @@
     fn init(&mut self, use_rsl: bool) {
         macro_rules! init {
             ($var:ident) => (
-                let mut $var = 0x9e3779b97f4a7c13;
+                let mut $var = w(0x9e3779b97f4a7c13);
             )
         }
         init!(a); init!(b); init!(c); init!(d);
@@ -312,14 +315,14 @@
 
         macro_rules! mix {
             () => {{
-                a-=e; f^=h>>9;  h+=a;
-                b-=f; g^=a<<9;  a+=b;
-                c-=g; h^=b>>23; b+=c;
-                d-=h; a^=c<<15; c+=d;
-                e-=a; b^=d>>14; d+=e;
-                f-=b; c^=e<<20; e+=f;
-                g-=c; d^=f>>17; f+=g;
-                h-=d; e^=g<<14; g+=h;
+                a=a-e; f=f^(h>>9);  h=h+a;
+                b=b-f; g=g^(a<<9);  a=a+b;
+                c=c-g; h=h^(b>>23); b=b+c;
+                d=d-h; a=a^(c<<15); c=c+d;
+                e=e-a; b=b^(d>>14); d=d+e;
+                f=f-b; c=c^(e<<20); e=e+f;
+                g=g-c; d=d^(f>>17); f=f+g;
+                h=h-d; e=e^(g<<14); g=g+h;
             }}
         }
 
@@ -331,10 +334,10 @@
             macro_rules! memloop {
                 ($arr:expr) => {{
                     for i in (0..RAND_SIZE_64 / 8).map(|i| i * 8) {
-                        a+=$arr[i  ]; b+=$arr[i+1];
-                        c+=$arr[i+2]; d+=$arr[i+3];
-                        e+=$arr[i+4]; f+=$arr[i+5];
-                        g+=$arr[i+6]; h+=$arr[i+7];
+                        a=a+$arr[i  ]; b=b+$arr[i+1];
+                        c=c+$arr[i+2]; d=d+$arr[i+3];
+                        e=e+$arr[i+4]; f=f+$arr[i+5];
+                        g=g+$arr[i+6]; h=h+$arr[i+7];
                         mix!();
                         self.mem[i  ]=a; self.mem[i+1]=b;
                         self.mem[i+2]=c; self.mem[i+3]=d;
@@ -361,7 +364,7 @@
 
     /// Refills the output buffer (`self.rsl`)
     fn isaac64(&mut self) {
-        self.c += 1;
+        self.c = self.c + w(1);
         // abbreviations
         let mut a = self.a;
         let mut b = self.b + self.c;
@@ -369,7 +372,7 @@
         const MP_VEC: [(usize, usize); 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
         macro_rules! ind {
             ($x:expr) => {
-                *self.mem.get_unchecked(($x as usize >> 3) & (RAND_SIZE_64 - 1))
+                *self.mem.get_unchecked((($x >> 3).0 as usize) & (RAND_SIZE_64 - 1))
             }
         }
 
@@ -450,7 +453,7 @@
         // See corresponding location in IsaacRng.next_u32 for
         // explanation.
         debug_assert!(self.cnt < RAND_SIZE_64);
-        self.rsl[(self.cnt % RAND_SIZE_64) as usize]
+        self.rsl[(self.cnt % RAND_SIZE_64) as usize].0
     }
 }
 
@@ -461,12 +464,12 @@
         let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u64));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
-            *rsl_elem = seed_elem;
+            *rsl_elem = w(seed_elem);
         }
         self.cnt = 0;
-        self.a = 0;
-        self.b = 0;
-        self.c = 0;
+        self.a = w(0);
+        self.b = w(0);
+        self.c = w(0);
 
         self.init(true);
     }
@@ -493,9 +496,9 @@
             other.fill_bytes(slice);
         }
         ret.cnt = 0;
-        ret.a = 0;
-        ret.b = 0;
-        ret.c = 0;
+        ret.a = w(0);
+        ret.b = w(0);
+        ret.c = w(0);
 
         ret.init(true);
         return ret;
diff --git a/src/lib.rs b/src/lib.rs
index cac7a6b..50984dc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -233,6 +233,7 @@
 use std::mem;
 use std::old_io::IoResult;
 use std::rc::Rc;
+use std::num::wrapping::Wrapping as w;
 
 pub use os::OsRng;
 
@@ -255,6 +256,11 @@
 pub mod os;
 pub mod reader;
 
+#[allow(bad_style)]
+type w64 = w<u64>;
+#[allow(bad_style)]
+type w32 = w<u32>;
+
 /// A type that can be randomly generated using an `Rng`.
 pub trait Rand : Sized {
     /// Generates a random instance of this type using the specified source of
@@ -590,10 +596,10 @@
 #[allow(missing_copy_implementations)]
 #[derive(Clone)]
 pub struct XorShiftRng {
-    x: u32,
-    y: u32,
-    z: u32,
-    w: u32,
+    x: w32,
+    y: w32,
+    z: w32,
+    w: w32,
 }
 
 impl XorShiftRng {
@@ -605,10 +611,10 @@
     /// this function
     pub fn new_unseeded() -> XorShiftRng {
         XorShiftRng {
-            x: 0x193a6754,
-            y: 0xa8a7d469,
-            z: 0x97830e05,
-            w: 0x113ba7bb,
+            x: w(0x193a6754),
+            y: w(0xa8a7d469),
+            z: w(0x97830e05),
+            w: w(0x113ba7bb),
         }
     }
 }
@@ -621,9 +627,9 @@
         self.x = self.y;
         self.y = self.z;
         self.z = self.w;
-        let w = self.w;
-        self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
-        self.w
+        let w_ = self.w;
+        self.w = w_ ^ (w_ >> 19) ^ (t ^ (t >> 8));
+        self.w.0
     }
 }
 
@@ -633,10 +639,10 @@
         assert!(!seed.iter().all(|&x| x == 0),
                 "XorShiftRng.reseed called with an all zero seed.");
 
-        self.x = seed[0];
-        self.y = seed[1];
-        self.z = seed[2];
-        self.w = seed[3];
+        self.x = w(seed[0]);
+        self.y = w(seed[1]);
+        self.z = w(seed[2]);
+        self.w = w(seed[3]);
     }
 
     /// Create a new XorShiftRng. This will panic if `seed` is entirely 0.
@@ -645,10 +651,10 @@
                 "XorShiftRng::from_seed called with an all zero seed.");
 
         XorShiftRng {
-            x: seed[0],
-            y: seed[1],
-            z: seed[2],
-            w: seed[3]
+            x: w(seed[0]),
+            y: w(seed[1]),
+            z: w(seed[2]),
+            w: w(seed[3]),
         }
     }
 }
@@ -659,8 +665,8 @@
         while tuple == (0, 0, 0, 0) {
             tuple = rng.gen();
         }
-        let (x, y, z, w) = tuple;
-        XorShiftRng { x: x, y: y, z: z, w: w }
+        let (x, y, z, w_) = tuple;
+        XorShiftRng { x: w(x), y: w(y), z: w(z), w: w(w_) }
     }
 }