Какие наиболее значимые биты устанавливаются при приведении к «более крупному» типу?

В C/С++, когда я выполняю следующее приведение:

uint8_t a = 0xAB;

//In C++
uint32_t b = static_cast<uint32_t>(a);

//In C
uint32_t c = (uint32_t)a;

Я предполагаю, что все старшие значащие биты «большего» типа (b) равны нулю. Гарантируется ли это стандартом при переходе от типа с меньшим количеством бит к типу с большим?

Это было бы скорее сломано, если бы приведение к более широкому типу изменило значение. Пожалуйста, выберите один язык

463035818_is_not_a_number 22.02.2023 16:28

Совет: найдите «знак-расширение». И как C, так и C++ не требуют какого-либо конкретного побитового представления целых чисел, поэтому (я полагаю, что могу ошибаться), что установка любых битов в любых стандартных значениях целочисленного типа может быть определена реализацией - мне придется проконсультироваться с спец.

Dai 22.02.2023 16:30

Если бы эти дополнительные биты не были нулями, у вас было бы другое значение.

NathanOliver 22.02.2023 16:32

Дополнительные целые числа 2 (т. е. целые со знаком) будут расширять MSBit, поэтому -1 int8_t по-прежнему будет -1 при назначении int32_t, а не 255.

franji1 22.02.2023 16:33

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

0___________ 22.02.2023 16:33

Добавление тега language-lawyer принудительно изменяет объем вопроса и делает недействительными существующие ответы.

463035818_is_not_a_number 22.02.2023 17:04

@ 463035818_is_not_a_number ОП явно хочет, чтобы поведение программы соответствовало стандарту, а не догадкам, как они писали: «Это гарантируется стандартом ...»

Jason Liam 22.02.2023 17:05

@JasonLiam тег языкового юриста обычно означает больше. Без тега «Да, это гарантировано» может быть хорошим ответом. Добавление тега делает недействительными уже существующие ответы.

463035818_is_not_a_number 22.02.2023 17:07

@JasonLiam One спрашивает, «что происходит». Другой спрашивает «главу и стих стандарта, что должно / разрешено происходить». Две разные вещи.

DevSolar 22.02.2023 17:07

@ 463035818_is_not_a_number Нет, просто сказать «да или нет» — это не ответ. Нужно также показать, почему именно так обстоит дело в соответствии со стандартом, если OP специально задал вопрос о поведении в соответствии со стандартом.

Jason Liam 22.02.2023 17:08

@DevSolar Нет, явное указание «глава и стих» не является обязательным. Некоторые вещи являются неявными и имеют здравый смысл. Если человек говорит, что стандарт говорит то или иное, то он должен показать, где это сказано, пока вопрос задавался для того и в этом случае он был задан.

Jason Liam 22.02.2023 17:09

@JasonLiam «да» или «нет» — это ответ на вопрос «а?». ТС, я с тобой не спорю. Я просто пытаюсь донести свою точку зрения до модов, которые, как я надеюсь, решат эту бессмысленную войну правок.

463035818_is_not_a_number 22.02.2023 17:09

@ 463035818_is_not_a_number Ясно, я думаю, что тег language-lawyer также сделает (в дополнение к этому) этот вопрос (и его ответы) более каноническим, чтобы будущие читатели могли непосредственно видеть поведение программы точно так, как это предписано стандартом.

Jason Liam 22.02.2023 17:13

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

John Bollinger 22.02.2023 17:15

@JasonLiam из описания тега «Используйте этот тег для вопросов, когда вас интересует формальная спецификация для определенного поведения на данном языке программирования [...]», нет никаких доказательств того, что это то, чего хочет здесь ОП, они действительно просто задают простой вопрос да/нет

463035818_is_not_a_number 22.02.2023 17:17
xkcd.com/1167
leosch 22.02.2023 17:23

@ 463035818_is_not_a_number Как я уже сказал, SO — это больше, чем сайт вопросов MCQ. Просто писать «правда или ложь» не является целью сайта. Люди, отвечающие на вопрос, должны объяснить (если ОП прямо задал вопрос, как в этом вопросе в моем понимании), цитируя соответствующие ссылки из стандарта. Но я тоже могу ошибаться.

Jason Liam 22.02.2023 17:23
Руководство для начинающих по веб-разработке на React.js
Руководство для начинающих по веб-разработке на React.js
Веб-разработка - это захватывающая и постоянно меняющаяся область, которая постоянно развивается благодаря новым технологиям и тенденциям. Одним из...
Разница между Angular и React
Разница между Angular и React
React и AngularJS - это два самых популярных фреймворка для веб-разработки. Оба фреймворка имеют свои уникальные особенности и преимущества, которые...
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
2
17
105
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Тип uint8_t — беззнаковый целочисленный тип.

uint8_t a = 0xAB;

Таким образом, значение будет сохранено, когда объект этого типа будет приведен к типу uint32_t, потому что объекты этого типа могут вмещать значение 0xAB.

На самом деле кастинг излишен. Вы можете просто написать

uint32_t c = a;

Вы даже можете написать

uint32_t a = 0xAB;
uint8_t c = a;

Потому что снова значение 0xAB может быть сохранено в объекте типа uint8_t.

Ответ принят как подходящий

Техническая терминология C и C++ в этой области немного различается. Я буду использовать терминологию C, но изложенные идеи применимы к обоим языкам.

Преобразования типов, такие как приведения типов в стиле C и C++ static_cast, являются операциями над значениями, а не над объектами, и их результаты также являются значениями, а не объектами. Представления значений операнда и результата, включая значения любых конкретных битов, не рассматриваются в спецификациях для этих операций.

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

Что касается вашего примера, вы спрашиваете...

Я предполагаю, что все старшие значащие биты «большего» типа (b) равны нулю. Гарантируется ли это стандартом при переходе от типа с меньшим количеством бит к типу с большим?

В свете (отдельных) спецификаций для представления целочисленных типов преобразование является средством сохранения значения.

  • Для неотрицательных операндов, если исходный и целевой типы являются целыми типами, а целевой тип представлен большим количеством битов значения, чем исходный тип, то биты значения представления результата целевого типа, которые не соответствуют биты значения в исходном представлении значения операнда примут значение 0.

  • Для отрицательных операндов, если исходный и целевой типы являются целочисленными типами (со знаком), а целевой тип представлен в форме дополнения до двух с большим количеством битов значения, чем исходный тип, то биты значения представления типа назначения результата которые не соответствуют битам значения в исходном представлении операнда, примут значение 1. Это называется «расширением знака».

Другие вопросы по теме