# Are Solidity numbers little endian, or big endian padded left?

Solidity says it stores numbers as little endian... but I don't understand how thats possible given that they are left padded.

``````const a = new Bn(256)
const b = new Bn(256 * 256)

a.toArray('le')
>> [0, 1]
b.toArray('le')
>> [0, 0, 1]
``````

That makes sense. The little byte is first.

However, integers are left padded in Solidity.

If you left pad both to 32 bytes, they'll both be

``````[0, 0, ..., 1]
``````

What am I missing or misunderstanding? Maybe it would be more accurate to say solidity numbers are big endian and padded left?

• Commented Nov 16, 2019 at 9:37

You're missing the fact that "left" doesn't indicate "bigger", just semantics.

It's not as if values in memory appear left or right to each other.

Consider the following 32-bit integer 0x00112233:

• It's little-endian representation is "0x33 at the lowest address ... 0x00 at the highest address"
• It's big-endian representation is "0x00 at the lowest address ... 0x33 at the highest address"

In both cases, when you write it down in your code, you pad it with zeros on the left side.

Any compiler, whether it is designated for little-endian architecture or for big-endian architecture, will interpret the exact same value (0x112233).

But each type of compiler will generate a different memory layout for this value.

You could say that within that memory layout, the compiler will pad to the left in the case of little-endian and to the right in the case of big-endian.

However, this padding will have no impact on how you write it down in your code (it's not as if you'll need to change 0x00112233 to 0x33221100 when you switch from little-endian to big-endian).

And again - this is just semantics, because values in memory do not appear left or right to each other.

The only way for you to view the difference is by viewing the number from lowest byte-address to highest byte-address (or vice-versa).

For example, here is how you could do this in a native language like C:

``````int x = 0x12345678;
char* p = (char*)&x;
for (int i = 0; i < sizeof(x); i++)
printf("%x\n",(int)p[i]);
``````

As far as I know, you cannot do this type of "direct memory access" in Solidity.

• Just for my understanding, if you shift in assembly (shl/shr), can’t you (indirectly) see the big/little endian difference ? For instance, shifting right a bytes (which is big endian) or shifting left a number (little endian) would only remove 0’s (if you stay within the mem slot ofc) ? ie shl 0x000012 or shr 0x120000 ? Commented Nov 3, 2021 at 23:27
• Like here or is it only a (pedagogic) way of seeing it ? jeancvllr.medium.com/… Commented Nov 3, 2021 at 23:29