Как вычесть два неподписанных ints с, повторяются или переполняются

Существует два неподписанных ints (X и Y), которые должны быть вычтены. x всегда больше, чем y. Однако оба X и Y могут повториться; например, если они были оба байтами, после того, как 0xff прибывает 0x00. Проблемный случай - то, если x повторяется, в то время как y не делает. Теперь x, кажется, меньше, чем y. К счастью x не повторится дважды (только однажды гарантируется). Принимая байты, x перенесся и теперь 0x2, тогда как y не имеет и является 0xFE. Правильный ответ x - y, как предполагается, является 0x4.

Возможно,

( x > y) ? (x-y) : (x+0xff-y);

Но я думаю, что существует иначе, что-то включающее 2 комплимента с?, и в этой встроенной системе, X и Y являются самыми большими неподписанными международными типами, таким образом добавление 0xff... не возможно

Что лучший способ состоит в том, чтобы записать оператору (выходной язык является C)?

19
задан mgag 14 January 2010 в 00:57
поделиться

5 ответов

При условии, что два unsigned :

  • Если вы знаете, что он должен быть «больше», чем другой, просто вычесть. Он будет работать при условии, что вы не обмотаны более чем раз (очевидно, если у вас есть, вы не сможете сказать).
  • Если вы не знаете, что один превышает другой, вычтете и представлял результат к подписанию int одинаковой ширины. Он будет работать при условии, что разница между ними находится в диапазоне подписанного int (если нет, вы не сможете сказать).

Чтобы уточнить: сценарий, описываемый исходным плакатом, кажется, сбивает с толку людьми, но типично для монотонно увеличивающихся счетчиков фиксированной ширины, таких как счетчики оборудования, или числовые номера в протоколах. Счетчик идет (например, для 8 бит) 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x01, 0x02, 0x03 и т. Д., И вы знаете, что из двух значений x и y, которые у вас есть, x приходит позже. Если x == 0x02 и y == 0xfe, вычисление xy (в качестве 8-битного результата) даст правильный ответ 4, предполагая, что вычитание двух n -битных значений оборачивает модуль 2 n - который C99 гарантирует для вычитания unsigned ценностей. (Примечание. Стандарт C не работает , гарантируют это поведение для вычитания значений .)

29
ответ дан 30 November 2019 в 02:04
поделиться

Может быть, я не понимаю, но что не так с:

unsigned r = x - Y;

13
ответ дан 30 November 2019 в 02:04
поделиться

В моем Firefox пункт меню

File->Save Page As->Web Page, Complete 

сохраняет все javascript, а также изображения и css. Подключаемый модуль не требуется.

-121--2258369-

Это довольно хороший вопрос, и я должен признать, что у меня нет ответа. Однако пару лет назад, когда я работал над Java-приложением и столкнулся с этой проблемой, я решил ее, зарегистрировав крючок отключения во время выполнения, который сделал бы то, что я хотел, чтобы приложение сделало до выхода. Это тяжелое решение, но оно сработало. Вы можете взглянуть на мой код и проверить, помогает ли он.

-121--1576007-

Вопрос, как указано, является запутанным. Вы сказали, что вычитаете неподписанные значения. Если x всегда больше y , как вы сказали, то x - y не может обернуться или переполниться. Итак, вы просто делаете x - y (если это то, что вам нужно) и все.

3
ответ дан 30 November 2019 в 02:04
поделиться

Чтобы повторить все остальные ответы, если вычесть оба и интерпретировать результат как неподписанный, то все будет в порядке.

Если только у вас нет явного контрпример.

Ваш пример x = 0x2, y= 0x14 не приведет к 0x4, это приведет к 0xEE, если только у вас нет больше ограничений по математике, которые являются нестабильными.

0
ответ дан 30 November 2019 в 02:04
поделиться

Вот еще немного подробностей, почему это «просто работает», когда вы вычитаете «меньшее» из «большего».

Вот пара моментов…
1. В аппаратном вычитании используется сложение: соответствующий операнд перед добавлением просто инвертируется.
2.В дополнении до двух (которое используется почти во всем) целое число инвертируется путем инвертирования всех битов и добавления 1.

Аппаратное обеспечение делает это более эффективно, чем это звучит из приведенного выше описания, но это основной алгоритм вычитания (даже когда значения беззнаковые).

Итак, давайте изобразим 2 - 250, используя 8-битные целые числа без знака. В двоичном формате мы имеем

  0 0 0 0 0 0 1 0  
- 1 1 1 1 1 0 1 0

. Мы отменяем вычитаемый операнд, а затем складываем его. Напомним, что для инвертирования мы инвертируем все биты, а затем добавляем 1. После инвертирования битов второго операнда мы имеем

0 0 0 0 0 1 0 1  

Затем после добавления 1 мы имеем

0 0 0 0 0 1 1 0  

Теперь мы выполняем сложение ...

  0 0 0 0 0 0 1 0   
+ 0 0 0 0 0 1 1 0

= 0 0 0 0 1 0 0 0 = 8, which is the result we wanted from 2 - 250
20
ответ дан 30 November 2019 в 02:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: