Change lab01 rotation functions parameter type #171
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Use
unsigned int
instead ofint
for bitwise rotate functions. The reason for this change is that signed integers should generally not be used as bitsets, since some arithmetic operators behave badly in the case of signed integers, as opposed to unsigned (particularly left and right shifts). Here, the problems withint
arise in the following ways:0x80000000
, with value2^31
, to a 32-bit signed integer, which can only represent values less than or equal to2^31 - 1
. Assigning this large value to anint
has implementation-defined behavior. Legal signed integer values with this particular bit representation (1
followed by 31 zeros) include two's complement-2^31
, sign-and-magnitude-0
etc. (depending on the encoding).rotate_left
impl shifts signed*number
to the left bybits
positions, though the C standard document specifies the result of this operation is*number * 2^(bits)
, and if this value is not representable byint
, then the behavior is undefined (this happens whenever a1
is shifted to or beyond the most significant bit).rotate_right
impl similarly shifts signed*number
to the right bybits
positions, adding the missing piece to the left by way of the|
operator. The assumption is that the shift leaves some0
bits to the left of*number
. However, if the most significant bit is1
(i.e., a negative value), the result of the right shift is implementation-defined. Modern platforms implement arithmetic right shift, which extends the sign of*number
by copying the most significant bit, leaving1
instead of0
to the left side of*number
.All of these problems can be avoided by using unsigned numbers instead, as they do not exhibit strange behavior with bit operators. Note that using signed integers for the right-hand operands of shift operators is not a problem, hence I left the
bits
parameter untouched.