Перейти: преобразование 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 4

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 is 0xffffffffffffffff (-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.