int8
, int128
, int256
While uint[n]
types can only contain positive integers, the int[n]
types can contain both positive and negative numbers. As you know, int[n]
variables store numbers ranging from -1 -> -(2 ^ (n-1))
on the negative side, and 0 -> ((2^n) - 1)
on the positive side. This means that for the three int[n]
types specified above, this would be their minimum and maximum values.
int[n] type | Minimum Value | Maximum Value |
---|---|---|
int8 | -128 | 127 |
int128 | -2^127 | (2^127) - 1 |
int256 | -2^255 | (2^255) - 1 |
When it comes to storage of int[n]
types, the positive values range from 0x00
in hex, (with the number of bytes after 0x
corresponding to the number of bytes of the int[n]
type) up till 0x7f
. While the negative numbers range from 0xff
to 0x80
backwards. It is reasonable as 0xff
is greater than 0x80
on hexadecimal face value, so is -1
greater than -128
on the decimal scale.
Value | Value | Value | Value | Value | Value | |
---|---|---|---|---|---|---|
0 | 1 | 2 | ... | 125 | 126 | 127 |
0x00 | 0x01 | 0x02 | ... | 0x7d | 0x7e | 0x7f |
-1 | -2 | -3 | ... | 126 | 127 | -128 |
0xff | 0xfe | 0xfd | ... | 0x82 | 0x81 | 0x80 |
int[n]
types are packed in a similar way, just like their uint[n]
counterparts.
You can try to store different int[n]
types on Remix to see their storage layouts.
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Yul {
// int<n> public variableName = value;
int8 public int8Value = -1; // Slot 0.
function getInt8() public view returns (bytes32) {
assembly {
mstore(0x80, sload(0x00))
return(0x80, 0x20)
}
}
}
🚨 Due to the tricky nature of the storage of
int[n]
types, apply more care when storing and manipulating values from storage.
🚨 Do not store negative
int[n]
values directly from your Yul block of code, Yul treats it as auint[n]
type overflow, meaning that-1
will be converted to(2^256) - 1
. This can lead to security breaches.