Перейти: преобразование uint64 в int64 без потери информации
Проблема со следующим кодом:
var x uint64 = 18446744073709551615
var y int64 = int64(x)
Есть то, что y
есть -1
. Без потери информации, является ли единственным способом преобразования между этими двумя типами чисел использовать кодер и декодер?
buff bytes.Buffer
Encoder(buff).encode(x)
Decoder(buff).decode(y)
Обратите внимание, что я не пытаюсь выполнить прямое числовое преобразование в вашем типичном случае. Меня больше волнует сохранение статистических свойств генератора случайных чисел.3 ответа:
Видеть -1 было бы совместимо с процессом, работающим как 32bits.
Смотрите, например, Go1.1 release notes (который ввел
uint64
)x := ^uint32(0) // x is 0xffffffff i := int(x) // i is -1 on 32-bit systems, 0xffffffff on 64-bit fmt.Println(i)
Использование
fmt.Printf("%b\n", y)
может помочь увидеть, что происходит (см. ANisus' Ответ )Как оказалось, OP wheaties подтверждает (в комментариях ), что он был запущен изначально в 32 битах (отсюда и этот ответ), но затем реализовать
18446744073709551615
is0xffffffffffffffff
(-1) в любом случае: см. АнисОтвет ;
Ваше преобразование не теряет никакой информации в преобразовании. Все биты останутся нетронутыми. Именно так:
uint64(18446744073709551615) = 0xFFFFFFFFFFFFFFFF int64(-1) = 0xFFFFFFFFFFFFFFFF
Попробуйте:
var x uint64 = 18446744073709551615 - 3
И у вас будет
y = -4
.
Например: игровая площадка
var x uint64 = 18446744073709551615 - 3 var y int64 = int64(x) fmt.Printf("%b\n", x) fmt.Printf("%b or %d\n", y, y)
Вывод:
1111111111111111111111111111111111111111111111111111111111111100 -100 or -4
Типы uint64 и int64 могут представлять 2^64 дискретных целочисленных значения.
Разница между ними состоит в том, что uint64 содержит только положительные целые числа (от 0 до 2^64-1), где as int64 содержит как отрицательные, так и положительные целые числа, используя 1 бит для хранения знака (от -2^63 до 2^63-1).Как уже говорили другие, если ваш генератор производит
0xffffffffffffffff
, uint64 будет представлять это как сырое целое число (18,446,744,073,709,551,615), тогда как int64 будет интерпретировать дополнение двух значение и возврат -1.