Is checking overflow disabled in method?


#1

I implemented Xorshift random number generation algorithm as bellow.
Then I noticed that when I run it, it doesn’t occur panic at the lines 35 and 36 while it does at the line 4.
In all these line arithmetic overflow should happen in the same way.
Is checking overflow disabled in method?
Why?

fn main(){
    Rand::new();
    for i in 0..100 {
        println!("{:032b}", (1 as u32) << i);
    }
}

struct Rand {
    x: u32,
    y: u32,
    z: u32,
    w: u32,
}

use std::io::Read;

impl Rand {
    fn new() -> Rand {
        let mut buffer = [0; 4];
        let _ = std::fs::File::open("/dev/urandom")
            .unwrap()
            .take(4)
            .read(&mut buffer);
        let mut seed = 0;
        for &s in buffer.iter() {
            seed <<= 8;
            seed |= s as u32;
        };
        let mut res = Rand { x: 123456789, y: 987654321, z:1000000007, w: seed };
        for _ in 0..10 { res.next(); };
        res
    }

    fn next(&mut self) -> u32 {
        println!("{:032b} {:032b}", self.x, self.x << 11);
        let t = self.x ^ (self.x << 11);
        self.x = self.y;
        self.y = self.z;
        self.z = self.w;
        self.w = (self.w ^ (self.w >> 19)) ^ (t ^ (t >> 8));
        self.w.clone()
    }
}

Output:

> rustc test.rs && ./test                                                                  [$?=101] 
00000111010110111100110100010101 11011110011010001010100000000000
00111010110111100110100010110001 11110011010001011000100000000000
00111011100110101100101000000111 11010110010100000011100000000000
00010000110100011010010101100110 10001101001010110011000000000000
11001001001110111111000100001100 11011111100010000110000000000000
00000000011010011001001101111010 01001100100110111101000000000000
11101101010011101010101110000010 01110101010111000001000000000000
01110000001010011101100111011000 01001110110011101100000000000000
01100110100011001111010101000000 01100111101010100000000000000000
00101010001100100100100010101000 10010010010001010100000000000000
00000000000000000000000000000001
00000000000000000000000000000010
00000000000000000000000000000100
00000000000000000000000000001000
00000000000000000000000000010000
00000000000000000000000000100000
00000000000000000000000001000000
00000000000000000000000010000000
00000000000000000000000100000000
00000000000000000000001000000000
00000000000000000000010000000000
00000000000000000000100000000000
00000000000000000001000000000000
00000000000000000010000000000000
00000000000000000100000000000000
00000000000000001000000000000000
00000000000000010000000000000000
00000000000000100000000000000000
00000000000001000000000000000000
00000000000010000000000000000000
00000000000100000000000000000000
00000000001000000000000000000000
00000000010000000000000000000000
00000000100000000000000000000000
00000001000000000000000000000000
00000010000000000000000000000000
00000100000000000000000000000000
00001000000000000000000000000000
00010000000000000000000000000000
00100000000000000000000000000000
01000000000000000000000000000000
10000000000000000000000000000000
thread '<main>' panicked at 'shift operation overflowed', test.rs:4

#2

In this expression, i must be strictly smaller than 32 (the number of bits in u32), so that’s the reason for the debug assertion. The other bit shifts you use don’t seem to be exceeding the bit size of the type.


#3

I see.
Thank you!