Why does padding add zeros to left, but left align adds zeros to right when performing bit manipulation?

79 Views Asked by At

I am not sure if this is a general bit manipulation related question or something specific to Ethereum. But I am reading a part of the ethereum specification here and I am confused by the bit related operations.

For instance, in the Example section a uint32 value of 69 padded to 32 bytes became 0x0000000000000000000000000000000000000000000000000000000000000045.

This I understand. Turn 69 to hex, which is 45 then pad it with 30 zeros.

But a value of "abc" after being left aligned became 0x6162630000000000000000000000000000000000000000000000000000000000

Now I am confused.

Why is it that the zeros here are added to the right? I understand where the 0x616263 comes from, which is the hex representation of "abc". But when padding the hex representation of 69 above, the zeros were added on the left, but with "abc" the zeros are being added on the right side. Why is this the case?

1

There are 1 best solutions below

0
On

Both are big-endian. In EVM the memory is handled in 32-byte blocks/buffers. So even if your data type is uint8 or uint32 it is still managed as uint256 values (occupies 32bytes).

0x0000000000000000000000000000000000000000000000000000000000000045 == 69n
0x4500000000000000000000000000000000000000000000000000000000000000 == 31209586552245380797759367053122912663576675554410933276260051939632835723264n

This is how the integers are stored, even the bits in a byte are anchored to the right:

00000011 === 3

Strings are simple memory buffers, from left to right. There are some EVM-related things to remember - as with everything, the strings are also saved into the 32bytes blocks. So if the strings length is just 5 bytes long, you get zeros afterward. If the length is larger, then in the first block you get just the length of the string value (also right anchored as the length is uint256), and the blocks after that hold the actual string data.

Big-/little-endian is not just about the anchor of data, but about the byte-order:

// 0x3045
// big-endian byte order
30 45
// little endian byte order
45 30