LINUX.ORG.RU

C, кастинг из char в unsigned long. Почему старшие биты long-а заполняются трешем?


0

2
char p = 128;
unsigned long l = p;

Лонг побитно получился такой:

1111111111111111111111111111111111111111111111111111111110000000

Ну да, знаковое в беззнаковое конвертировать — это конечно ербалайство, спору нет. Но всё равно интересно, как оно внутри так устроено, что так получается? Ведь если сделать unsigned char = char, то получилось бы 128, зачем в лонге единицы появились?

★☆

Последнее исправление: kiverattes (всего исправлений: 2)

у тебя char переполнился, что ты хотел

anonymous
()

При статическом приведении мусора не бывает. char переполнился, туда записалось -128. Потом оно отнялось от INT64_MAX.

Dendy ★★★★★
()

У тебя чар отрицательный, и оно сконвертировалось с распространением знакового разряда

buddhist ★★★★★
()

-128 +127, лалка срочно коммимером в ядро я щетаю

anonymous
()

1000000011111111111111111111111111111111111111111111111111111111

0b1111111111111111111111111111111111111111111111111111111110000000

У тебя конвертор неправильный.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Да, я просто распечатывал с младшего байта. Но сцуко почему так? Зачем это расширение знакового бита? Почему не одна единичка в самом старшем разряде?

kiverattes ★☆
() автор топика

зачем в лонге единицы появились?

Вот и выросло нувыпонели.

LamerOk ★★★★★
()

ты так скор набиваешь?

anonymous
()
Ответ на: комментарий от kiverattes

Какой кастинг тебе неясен? Из отрицательного числа в дополнительном коде из знаковой переменной в положительное число в беззнаковой?

yoghurt ★★★★★
()
Ответ на: комментарий от kiverattes

А-а, ты хочешь знать, почему -1 не записывается в виде «0b10000001»? Такой вариант есть, но он требует особой логики при складывании чисел со знаком. Использование дополнительного кода позволяет обойтись беззнаковым сумматором, который работает для любых комбинаций.

Кстати, в варианте записи знака старшим битом будут два ноля, +0 и -0. Разные.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Нет, я понимаю зачем 1 в старшем разряде. Я хочу знать, зачем фигачить столько единичных битов в лонге при конвертации.

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

Так написано

4.7 Integral conversions

 ISO/IEC

(...)

2 If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2 n where n is the number of bits used to represent the unsigned type). [Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). ]

(2003й стандарт)

yoghurt ★★★★★
()
Ответ на: комментарий от kiverattes

Я хочу знать, зачем фигачить столько единичных битов в лонге при конвертации.

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

i-rinat ★★★★★
()
Ответ на: комментарий от kiverattes

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

yoghurt ★★★★★
()
Ответ на: комментарий от kiverattes

Ты ответы читаешь? Люди тратят время на ответ по существу, а ты даже не удосуживаешь себя пониманием прочитанного.

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

d ★★★★
()
Ответ на: комментарий от kiverattes

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

intelfx ★★★★★
()
Ответ на: комментарий от d

а ты даже не удосуживаешь себя пониманием прочитанного

Он просто троллит.

i-rinat ★★★★★
()
Ответ на: комментарий от kiverattes

Попробуй это число распечатать как знаковый char.

BRE ★★
()

На твоей платформе char это знаковый тип. Поэтому в p хранится значение "-128", а не «128». При конверсии к unsigned значению к данному значению прибавляется 2^64 (потому что так написано в стандарте) и результат ты видишь (2^64 + (-128)). Если бы char у тебя был беззнаковый (на некоторых платформах такое бывает), у тебя бы получилось то, что ты ожидаешь.

Legioner ★★★★★
()

Курс уже закончился, но я настоятельно рекомендую прослушать.

pon4ik ★★★★★
()
Ответ на: комментарий от kiverattes

Почему недостаточно одной в старшем разряде?

По кочану!

LongLiveUbuntu ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.