C: 8x8-> 16 битов умножают точность, гарантируемую целочисленными продвижениями?

Я пытаюсь выяснить, гарантирует ли Стандарт C (C90, хотя я отделываюсь от Derek Jones, аннотировал книгу C99), что я не потеряю точность, умножающую два неподписанных 8-разрядных значения и хранящую к 16-разрядному результату. Оператор в качестве примера следующие:

unsigned char foo;
unsigned int foo_u16 = foo * 10;

Наш компилятор Keil 8051 (v7.50 в настоящее время) генерирует инструкцию MUL AB, которая хранит MSB в регистре B и LSB в аккумуляторе. Если я бросил нечто к неподписанному интервалу сначала:

unsigned int foo_u16 = (unsigned int)foo * 10;

затем компилятор правильно решает, что я хочу неподписанный интервал там, и генерирует дорогой вызов к целому числу на 16x16 битов, умножают стандартную программу. Я хотел бы спорить вне обоснованного сомнения, что эта защитная мера не необходима. Когда я считал целочисленные продвижения, описанные в 6.3.1.1, эффект первой строки должен состоять в том, как будто нечто и 10 были продвинуты на неподписанный интервал, умножение, выполненное, и результат, сохраненный как неподписанный интервал в foo_u16. Если компилятор знает инструкцию, которая делает 8x8-> умножение на 16 битов без потери точности, тем лучше; но точность гарантируется. Я читаю это правильно?

С наилучшими пожеланиями, Craig Blome

5
задан Craig Blome 22 April 2010 в 18:49
поделиться

1 ответ

Продвижение гарантировано, но продвижение осуществляется по типу signed int , если диапазон unsigned char попадает в диапазон целое число со знаком . Итак (при условии, что он подходит) с точки зрения языка ваш

unsigned int foo_u16 = foo * 10; 

эквивалентен

unsigned int foo_u16 = (signed) foo * 10; 

, в то время как то, что вы, по-видимому, хотите, - это

unsigned int foo_u16 = (unsigned) foo * 10; 

. Результат умножения может быть другим, если он (результат) не соответствует диапазон подписанных int .

Если ваш компилятор интерпретирует это иначе, это может быть ошибка в компиляторе (опять же, в предположении, что диапазон unsigned char попадает в диапазон signed int ).

5
ответ дан 14 December 2019 в 19:06
поделиться
Другие вопросы по тегам:

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