Расчет смещени бит & lt; продолжает возвращать неправильное значение [duplicate]

Добавление ответа Мэтта для нескольких хостов.

пример ввода будет 192.0.2.10,192.0.2.11

- hosts: localhost
  gather_facts: no
  vars_prompt:
  - name: target_host
    prompt: please enter the target host IP
    private: no
  tasks:
    - add_host:
        name: "{{ item }}"
        groups: dynamically_created_hosts
      with_items: "{{ target_host.split(',') }}"


- hosts: dynamically_created_hosts
  tasks:
  - debug: msg="do things on target host here"
56
задан Ishq 9 February 2011 в 14:48
поделиться

5 ответов

Негативные целые числа в правой части - неопределенное поведение на языке C.

ISO 9899: 2011 6.5.7 Операторы битового сдвига:

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

66
ответ дан Lundin 21 August 2018 в 12:50
поделиться
  • 1
    Кстати, если в вашей книге не упоминалось, что это неопределенное поведение, вы должны подумать о получении другой книги. – Lundin 9 February 2011 в 14:54
  • 2
    В зависимости от того, что еще говорится в книге, вы можете утверждать, что это именно то, что она говорила (хотя она могла быть более четкой). «На одной машине происходит что-то». неявно означает, что это может случиться не с другими. – 3Doubloons 17 February 2011 в 04:57
  • 3
    Если это не сработает, будет ли это какая-то операция, которая будет иметь эквивалентное поведение для желаемого поведения в вопросе? Кажется грустным написать уравнение для этой конкретной операции :( Я пытаюсь сделать правый сдвиг, который делает 1 равным 0. – patrik 11 February 2015 в 16:46
  • 4
    В чем причина неопределенности, а не реализация, определенная здесь? Например. возникает ли какая-то важная архитектура? – Ciro Santilli 新疆改造中心 六四事件 法轮功 26 May 2015 в 10:11
  • 5
    @CiroSantilli 六四 事件 法轮功 Много неопределенного поведения связано с недостатками стандартного комитета C, а не с некоторыми обоснованными соображениями об аппаратных ограничениях. Но в этом случае я не вижу много возможностей для улучшения: если стандарт принудительно продвигал правый операнд к неподписанному типу, вы все равно бы получили нечто вроде a << (unsigned int)-5, что означало бы a << 0xFFFFFFFB, что также UB приведенным выше текстом. – Lundin 26 May 2015 в 13:12

Как уже ответили другие члены, он вызывает неопределенное поведение. То, что я хотел бы упомянуть здесь, - это то, что вы цитируете из книги («На одной машине»), кажется, частичной. Он не обобщает поведение. Книга также могла бы объяснить, что поведение не определено в соответствии со стандартом. BTW, я просто проходил «Новый стандарт C - экономический и культурный комментарий» и нашел это заявление:

Инструкция Intel Socket Intel для SAL (сгенерированная как gcc, так и Microsoft C ++ для оценки слева -shifts) использует только нижние пять бит величины сдвига

. Это очень хорошо объясняет, почему сдвиг влево -5 может привести к сдвигу влево 27 (для представления дополнения 2 отрицательного числа)

16
ответ дан Anand 21 August 2018 в 12:50
поделиться
  • 1
    Я уверен, что «На одной машине» предложение в книге OP служит только примером, сразу после того, как указано, что это неопределенное. Это на самом деле один из хороших примеров, которые «неопределенные» действительно означает что угодно, а не просто «чистые». внезапное завершение выполнения программы. Если использовать этот способ, не имеет смысла создавать впечатление, что сдвиг влево на 27 - это то, что вы имеете право ожидать. – Pascal Cuoq 9 February 2011 в 18:05
  • 2
    +1 для ответа на часть вопроса ", что именно происходит [на цитируемой" одной машине "] при сдвиге с отрицательным сдвигом". Конечно, UB - UB, и поэтому мы не должны ничего с этим делать, но это объяснение чрезвычайно иллюстративно относится к тем опасностям, которые привели их к make его UB. (мой мозг всегда хочет сказать «но почему он не может быть определен для буквенных целых чисел», но потом я думаю больше и понимаю, что это абсурдно ;-) – underscore_d 30 May 2016 в 19:51

Если значение, которое вы смещаете, является 32-битной переменной, сдвиг -5 переходит в «цикл» и сдвигает вперед 27. Сдвиг может выполняться только «без знака».

1
ответ дан arnorhs 21 August 2018 в 12:50
поделиться
  • 1
    Но если 32-битная переменная будет подписана, целочисленные рекламные акции не изменят подпись -5. И тогда поведение не определено, и программа может свободно останавливаться и загораться. – Lundin 9 February 2011 в 14:57
  • 2
    вероятно. В любом случае, я думаю, что это плохая практика :) – arnorhs 9 February 2011 в 15:10

Поведение неопределено.

В 5-битовой двоичной арифметике, two's-complement -5 имеет то же двоичное представление, что и unsigned +27, что, вероятно, объясняет эту конкретную платформу.

11
ответ дан Oliver Charlesworth 21 August 2018 в 12:50
поделиться
  • 1
    5-битная двоичная арифметика - вещь? Как будет определяться символ? – CIsForCookies 18 July 2017 в 05:56
  • 2
    @ClsForCookies - на электрическом уровне это реальная вещь. Нет ничего особенного в 8. – Oliver Charlesworth 18 July 2017 в 06:10
  • 3
    8 специально для того, чтобы быть силой 2. – user202729 26 March 2018 в 06:16
int main()
{
    unsigned int a = 1;
    printf("%u\n",a<<(-1));
    return 0;
}

Выходной сигнал: 2147483648.

Вот мое предположение и подтверждение: (просто предположение!) [/ ​​g1]

1. «& lt; правый операнд должен быть неподписанным типом int,

, поэтому, во-первых, (int) «-1» будет введен в (unsigned int) «-1». Причина Тип int представляет собой представление с двумя дополнениями, результат будет равен 2 ^ 32-1 (без знака int)

2.Due на номер 2 ^ 32-1 больше, чем цифра максимального смещения, 2 ^ 32 - 1 будет mod 32, что равно 27

. Я также пробовал некоторые другие правильные номера операндов, а результаты ручного вычисления с допущенными правилами будут одинаковыми с каким продуктом моей IDE.

Я пытаюсь найти некоторые поддерживающие официальные документы, ведь можно проверить, правильно ли мое предположение или нет. Может быть, вы можете мне сказать.

1
ответ дан Wu Little 21 August 2018 в 12:50
поделиться
Другие вопросы по тегам:

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