Поскольку это похоже на учебное упражнение, которое вы хотите решить самостоятельно, вот два совета:
Шестнадцатеричная цифра представляет четыре бита, поэтому каждая базовая цифра - 65 536 состоит из четырех шестнадцатеричных цифр. Поэтому вы можете читать цифры в группах по четыре, без необходимости преобразования в или из десятичного числа. Тот же алгоритм, который вы узнали для декодирования четырех десятичных цифр, будет работать для шестнадцатеричного числа, за исключением того, что умножения будут еще более эффективными, поскольку компилятор оптимизирует их в инструкции сдвига влево.
Вы должны использовать тип uint16_t
из<stdint.h>
для этой арифметики, так как она точно правильного размера и без знака. Арифметическое переполнение без знака определяется как обтекание, что вам и нужно. Переполнение со знаком - неопределенное поведение. (Или #include <cstdint>
, за которым следует using std::uint16_t;
, если вы предпочитаете.)
Чтобы добавить цифры в любую базу b , возьмите сумму цифр по модулю b . Это будет еще проще, когда b имеет степень 2, потому что x86 и многие другие процессоры имеют 16-битную инструкцию добавления без знака, которая делает это аппаратно, и на любой машине, которая этого не делает,компилятор может оптимизировать это до битовой маски & 0xFFFFU
.
В обоих случаях вы можете, если хотите, выписать двоичные оптимизации вручную, используя <<
и &
вместо *
и %
. Это может даже немного улучшить сгенерированный код, если вы используете математику со знаком, а не без знака. Однако любой современный компилятор достаточно умен, чтобы выполнить такую микрооптимизацию за вас. Вам лучше не оптимизировать преждевременно, а писать код, который легче читать и понимать.