Hello,
From https://nim-lang.org/docs/tut1.html#basic-types-integers:
Most often integers are used for counting objects that reside in memory, so int has the same size as a pointer.
So what is the "size of the pointer"? Is it the same as the max int resolution on my machine (int64)?
I believe so as this snippet:
import math, strformat
let
int_low = low(int)
int_low_2power = log2(-int_low.float).int
int32_low = low(int32)
int32_low_2power = log2(-int32_low.float).int
int64_low = low(int64)
int64_low_2power = log2(-int64_low.float).int
echo fmt"int: {low(int)} (-2^{int_low_2power}) -> {high(int)} (2^{int_low_2power} - 1)"
echo fmt"int32: {low(int32)} (-2^{int32_low_2power}) -> {high(int32)} (2^{int32_low_2power} - 1)"
echo fmt"int64: {low(int64)} (-2^{int64_low_2power}) -> {high(int64)} (2^{int64_low_2power} - 1)"
evals to:
int: -9223372036854775808 (-2^63) -> 9223372036854775807 (2^63 - 1)
int32: -2147483648 (-2^31) -> 2147483647 (2^31 - 1)
int64: -9223372036854775808 (-2^63) -> 9223372036854775807 (2^63 - 1)
But then I don't understand why this fails:
import random
echo rand(9223372036854775807)
The failure is:
nim_src_yz0syY.nim(5, 10) Error: type mismatch: got <int64>
but expected one of:
proc rand[T](r: var Rand; x: HSlice[T, T]): T
proc rand(max: float): float
proc rand(max: int): int
proc rand(r: var Rand; max: float): float
proc rand[T](r: var Rand; a: openArray[T]): T
proc rand[T](a: openArray[T]): T
proc rand[T](x: HSlice[T, T]): T
proc rand(r: var Rand; max: int): int
expression: rand(9223372036854775807'i64)
If rand is accepting int, and if int and int64 ranges are the same, shouldn't the type of 9223372036854775807 be auto-inferred as int instead of int64 when given to a function accepting int (and not int64)?
Doing this fixes this error:
import random
echo rand(9223372036854775807.int)
So should we just cast each time? Is that advisable?
First issue is there is no rand(int64) there is rand(int) though, int can be 32 or 64 bit. There should be probably be an rand(int64) version. Problem solved.
A much more interesting is the auto promotion of numbers to int64. The current logic is that if number can fit into in32 it stays int, if it can't then it is made int64.
I think it was supposed to be a convince feature for 32 vs 64 bit platforms.
Code line where this feature is implemented is here: https://github.com/nim-lang/Nim/blob/devel/compiler/lexer.nim#L596
# Promote int literal to int64? Not always necessary, but more consistent
if result.tokType == tkIntLit:
if (result.iNumber < low(int32)) or (result.iNumber > high(int32)):
result.tokType = tkInt64Lit
I don't know why this feature was put in, but the reason why I would want to keep this feature is that nim can compile to 32 and 64 bit platforms. When you create a large int literal on a 32 bit system you probably want a 64 bit int. When you are on an 64 bit system, you probably want your code to be mostly compatible with 32 bit system as well.