# integers as object
print(type(100))
# integer size, because integer is an object, it is not a pure 'integer', it has overhead of reference count
import sys
print(sys.getsizeof(0)) # 24 pre-python 3.10
print(sys.getsizeof(1)) # 4 bytes on top(28)
print(sys.getsizeof(2**1000)) #much larger size, the run time is longer
# object header 16 byte; type pointer 8 byte, reference count 8 byte, integer value
import struct
# print(f"c type integer size: {struct.calcsize('i')})
# integer base
print(int("101",2))
print(int("101",36)) # max base number + a..z
print(bin(10))
print(oct(10))
print(hex(10))
print(36*36+1)
# integer operator result
print(type(2+3))
print(type(3-2))
print(type(2*3))
print(type(2**3))
print(type(2/3)) # always float
import math
a = math.floor(3.15)
b = math.floor(3.999)
c = math.floor(-3.15) # why ?
print(a,b,c)
# division operator a//b = math.floor(a/b) only for positive number
a = 33
b = 16
print(a/b)
print(a//b)
print(math.floor(a/b))
# negative number, try different -ve, results are different
a = -33
b = 16
print('{0}/{1} = {2}'.format(a,b,a/b))
print('trunc({0}/{1}) = {2}'.format(a,b,math.trunc(a/b)))
print('{0}//{1} = {2}'.format(a,b,a//b))
print('floor({0}//{1}) = {2}'.format(a,b,math.floor(a/b)))
# modula operator a = b * (a//b) + a % b
# 13/4 - 3..1
# -13/4 - -4..3
# 13/-4 - -4..-3
# -13/-4 - 3..-1
a = -13 # try -ve
b = 4
print('{0}/{1} = {2}'.format(a,b,a/b))
print('{0}//{1} = {2}'.format(a,b,a//b))
print('{0}%{1} = {2}'.format(a,b,a%b))
print(a == b * (a//b) + a%b)