Я дал 8 шестнадцатеричных цифр (в качестве примера):
long a0 = 00
long a1 = 2E
long a2 = E8
long a3 = A0
long a4 = 58
long a5 = 0F
long a6 = 37
long a7 = FF
и я хочу напечатать это в десятичном формате.
Итак, я пробовал:
long long Decimal = (pow(16, 14) * a) + (pow(16, 12) * a1) + (pow(16, 10) * a2) + (pow(16, 8) * a3) + (pow(16, 6) * a4) + (pow(16, 4) * a5) + (pow(16, 2) * a6) + (pow(16, 0) * a7);
но я получаю десятичное число, которое не является правильным десятичным числом. Что касается примера, десятичное значение равно 13203624298493951, но я получаю 13203624298493952.
Спасибо ребята за помощь
Вы путаете понятия значения и формата вывода. Просто сохраните значение в типе unsigned
, который гарантированно будет 64-битным (или более), и распечатайте его с соответствующим форматированием. Например, unsigned long long value = 0x002EE8A0580F37FF
и распечатайте его в соответствующем формате, например printf("%llu\n", value)
.
@M.M: Re «pow
является функцией с плавающей запятой и потеряет точность».: На самом деле, все вызовы pow
в этом случае должны возвращать точно правильные результаты. Фактические ошибки возникают в последних дополнениях.
pow
использует арифметику с плавающей запятой и возвращает результат double
, что приводит к тому, что остальная часть арифметики в вашем выражении использует double
. Арифметика double
с плавающей запятой в вашей реализации C не имеет достаточной точности для точного представления чисел, с которыми вы работаете.
Вместо (pow(16, 14) * a0)
используйте (long long) a0 << 4*14
. Здесь используется целочисленная арифметика, и результаты будут точными, если значения не переполняют тип long long
.
Обратите внимание, что если может быть установлен старший бит a0
(рассматривая его как восьмибитное число), что означает, что окончательный результат должен быть отрицательным числом, тогда (long long) a0 << 4*14
переполнит 64-битный тип long long
. Вам нужно будет написать другой код для обработки случаев с отрицательными числами. Если вы хотите, чтобы все результаты были беззнаковыми, а не отрицательными, используйте unsigned long long
вместо long long
.
pow
является функцией с плавающей запятой и теряет точность. Вместо этого вы должны использовать целочисленные операции (и следить за тем, чтобы не было переполнения). Посмотрите на оператор<<
. гдеa << b
означает a * (2 ^ b)