- Types
- newly declared variables have a default value dependent on its type
- || and && short-circuit
uint
= uint256
, int
= int256
- max type value:
- in the past:
uint(-1)
- now this is a compilation error
- now:
type(uint).max
- arithmetic is checked by default
- intermezzo: two's complement
- 0 … (2^255 - 1) => positives
- how many positive numbers are there?
- (2^255 - 1) - (1) + 1 = 2^255 - 1
- 2^255 => -2^255
- 2^256 - 1 => -1
- how many negative numbers?
- (2^256 - 1) - (2^255) + 1 = (2*2^255 - 1) - (2^255) + 1 = 2^255
- eg for uint8:
- 0 = 0
- 1 = 1
- 2 = 2
- ...
- 255 = 255
- eg for int8:
- 1 zero, 127 positive, 128 negative
- encoding:
- raw = interpreted
- 0 = 0
- 1 .. 127 = positives
- 128 (0x80) = -128
- 129 = -127
- ...
- 255 = -1
- 1 = -1 + 2 = 0xff + 0x02 = 0x01 = 1
- 1 + 2 = 0x80 + 0x02 = 0x82 = -3
- there is one more negative number than positive!
- bit operations are performed on two's complement (for signed numbers (integers))
- eg,
~int(0) == int(-1)
- in two's complement:
int(0) == 0...0
~int(0) == 1...1
int(-1)
== 1...1
- shifts
- type of shift operation has type of left operand
- right operand must be unsigned type (otherwise compilation error)
x << y == x * 2**y mod 2**256
x >> y == x / 2**y
(rounded down (towards negative infinity))
- before 0.5.0, this rounded towards zero (so up for negative
x
)
- overflow checks are not performed on shift operations!
x
only works for signed ints
- if
x = type(int).min
, then:
- in an unchecked block:
- otherwise:
x
will result in runtime error
- division
- 5 / 2 = 2
- 5 / 2 = -2 (rounding towards zero)
- NOT: -5 / 2 = -3 (rounding towards negative infinity)