Преобразование Python Hex в Signed Integer - PullRequest
0 голосов
/ 04 января 2019

Я отлаживаю программу C, которая принимает ввод через scanf (), используя% ld в качестве формата.

Мне нужно отправить вход такой, чтобы он равнялся 0xfffffffffffffffa.

Если я преобразую вышеприведенное шестнадцатеричное значение в десятичное с использованием Python, я получу: 18446744073709551610, как показано ниже:

>>> a = 0xfffffffffffffffa
>>> a
18446744073709551610L

Однако, когда я отлаживаю программу, я вижу, что значение было прочитано программой как: 0x7fffffffffffffff

Итак, есть ли способ сгенерировать десятичную дробь так, чтобы scanf () считал ее как 0xfffffffffffffffa вместо 0x7fffffffffffffff?

1 Ответ

0 голосов
/ 04 января 2019

Существует 2 спецификаторов преобразования для scanf для чтения десятичных чисел. u считывает десятичное целое без знака - в переменную целое число без знака , а d читает десятичное целое со знаком (в переменную со знаком целочисленный тип). При чтении десятичного целого числа со знаком максимум для 64-битного номера дополнения до 2 будет 2 ** 63 - 1, т.е. 9223372036854775807. При совпадении числа, превышающего это, scanf все равно будет соответствовать ему, но для соответствующего аргумента будет установлено максимальное значение.

Для беззнаковых 64-битных максимумов будет 2 ** 64 - 1. 18446744073709551610 будет работать для вход без знака , но вам нужен номер со знаком, для которого 0xfffffffffffffffa является представлением дополнения 2. Это на самом деле

>>> 0xfffffffffffffffa - 2 ** 64
-6

, потому что отрицательные числа преобразуются в беззнаковые путем многократного добавления или вычитания одного, большего, чем максимальное значение, пока значение не попадает в диапазон - теперь мы инвертируем операцию и получаем -6.


Обратите внимание, что некорректно сканировать в объект, используя %ld и , а затем печатать его значение, используя %lx, как вы, похоже, делаете, если только переменная не является знаком int и printf вызов имеет приведение аргумента к unsigned - потому что %lx требует unsigned long int! Если ваш компилятор не предупреждает об этом, добавьте параметр, например -Wall, чтобы включить дополнительную диагностику.

...