tuffy / bitstream-io

Library for reading/writing un-aligned values from/to streams in big-endian and little-endian formats
Apache License 2.0
52 stars 20 forks source link

`write_signed` cannot handle 32 bits #3

Open kawogi opened 5 years ago

kawogi commented 5 years ago

Running the code

BitWriter::endian(Vec::new(), LittleEndian).write_signed(32, 0).unwrap();

results in the following error message excessive value for bits written (same for BigEndian and all other values)

Ashymad commented 4 years ago

Yup, I've run into this issue as well. It generally happens when you try to write_signed() a value with the exact number of bits as the bit number parameter. In the example above you try to write 32 bits of a 0 (which defaults to 0i32 in Rust). The problem is caused by this assertion: https://github.com/tuffy/bitstream-io/blob/29973ff72d24a4ac8076251689df4512394e9e64/src/write.rs#L215-L219 The write_signed() function calls write() on value with sign bit removed and bits - 1 as the bits parameter, however as the type is signed the operation U::one() << bits moves 1 into the sign bit resulting in the minimum signed int value for the type. As every possible input value is greater than the minimum type value the error is raised.

For example let's try to write_signed(8, 0i8). 0i8 is 0b00000000 in binary. The sing bit 0 is pushed into the queue and write(7, 0i8) is called. Computing 1i8 << 7 == 0b00000001 << 7 results in 0b10000000 == -128i8. 0 is greater than -128 so the error is raised.

sdroege commented 11 months ago

This was fixed in https://github.com/tuffy/bitstream-io/commit/5c5dd5a35e32a01e185b999099f2f413275f4d38 it seems