Hello, everyone.

I’m reading the storage layout docs and I’m puzzled by one of the closed formulas provided for the concrete example of an array `uint24[][] x`

.

The docs say that the storage slot of element `x[i][j]`

is `keccak256(keccak256(p) + i) + floor(j / 10)`

where `p`

is the slot where `x`

is stored (I’ve also substituted `floor(256 / 24)`

with `10`

). So far so good, it all checks out.

However, they then say that, to recover the element from the slot data `v`

you have to compute `(v >> ((j % 10) * 24)) & type(uint24).max`

. Now, I agree that you have to right-shift `v`

and then AND it with the `uint24`

bitmask. But the shift quantity looks wrong to me: `(24 * j%10)`

is the amount of bits *to the left* of the element. Shouldn’t we instead shift by `256 - (24 * (j%10 + 1))`

, which is the amount of bits sitting *at the right* of the element?

Thanks to all for the help!

Cheers

Shifting right by `24 * (j % 10)`

and then taking the least significant 24 bits via the uint24-mask, means that the data in the array is represented in Little-Endian format.

Shifting right by `256 - 24 * (j % 10 + 1)`

and then taking the least significant 24 bits via the uint24-mask, means that the data in the array is represented in Big-Endian format.

An example of how the value 0x12345678 is stored at address 100 in memory, might help illustrating the difference between these two forms of data-representation:

```
+---------+---------------+------------+
| Address | Little Endian | Big Endian |
+---------+---------------+------------+
| 100 | 0x78 | 0x12 |
| 101 | 0x56 | 0x34 |
| 102 | 0x34 | 0x56 |
| 103 | 0x12 | 0x78 |
+---------+---------------+------------+
```

Hi, thanks for the answer!

I think I figured this out. So, Solidity actually does store integers in little-endian, but that detail is abstracted away (much like C does): in other words, `>>`

shifts towards the *least significant bits* (not necessarily right-wards then), so it translates to a **left-shift opcode**. Thus, when we do `v >> something`

we are actually shifting left, in storage, and that’s why the closed formula is correct.

Does that make sense?

That’s indeed the definition of `>>`

, aka *shift right*.

That’s obviously just a matter of the terminology used, which is designated for describing the nature of the operation in a more verbose (human-readable) manner.

It’s not like those bit are physically sitting somewhere, then moved to somewhere on the right hand side of their original location.

What I meant to emphasize is, that the data in the array is ultimately stored in Little Endian order, meaning that the value stored in cell N represents data which is “least significant” compared with the value stored in cell N+1.

For example, when storing the data `0x12345678`

in a byte-array:

- The value stored in cell 0 is
`0x78`

- The value stored in cell 1 is
`0x56`

- The value stored in cell 2 is
`0x34`

- The value stored in cell 3 is
`0x12`