2016-02-26 4 views
1

данных эта операция:Арифметические операции на int32 и int64 со скобками

int64_t a_int64, b_int64 = WHATEVER1; 
int32_t c_int32 = WHATEVER2; 

a_int64 = b_int64 - (c_int32 * 1000000); 

способствовало ли c_int32 к int64_t до умножения? Я знаю, что все целые числа продвигаются как минимум до «int» до любых арифметических операций и до размера большего операнда для двоичных операторов, если он имеет более высокий ранг, чем int. Но операции внутри круглых скобок обрабатываются отдельно от (второй) операции, вычитания?

+2

- просто используйте '1000000ULL', чтобы указать, что оба аргумента умножения должны быть продвинуты как минимум до 64 бит. –

+3

Примечание:'() 'являются скобками. Скобки - '[]'. – Olaf

+1

@ Lashane: Правильно будет использовать макрос 'INT64_C'. И OP использует целые числа со знаком, суффикс 'U' ошибочен. – Olaf

ответ

2

Но являются операции внутри скобок обрабатывается отдельно от (вторых) операций, вычитание?

Да; акции, участвующие в оценке c_int32 * 1000000, никоим образом не зависят от контекста. Любые необходимые преобразования из-за этого контекста происходят после результата.

Тем не менее, c_int32 * 1000000 четко определен только в тех случаях, когда он не переполняется; и в таких случаях не имеет значения, происходит ли 64-битное продвижение до или после умножения. Таким образом, компилятор может законно сделать это в любом случае (например, если он видит некоторые возможности оптимизации).

2

From another good SO post on the topic:

С99, §6.4.4.1

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

Таблица 6

int 
long int 
long long int 

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

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

a_int64 = b_int64 - ((int64_t)c_int32 * 1000000LL); 
+0

Этот ответ не является неправильным, но вместо того, чтобы отвечать на вопрос OP, он предполагает правильный ответ, в середине разговора о других вещи. ОП задал конкретный, разумный вопрос; любой ответ должен, если ничего другого, ответить на него. – ruakh

+0

@ruakh Я утверждаю, что вышеперечисленные ответы на вопрос OP. Это «зависит» от значения самого литерала. Я отмечаю, что в 32-битной системе он будет вписываться в 32-битный 'int'. Чтобы быть более явным, литерал будет оцениваться как 'int', а для наиболее возможных значений' c_int32' произойдет переполнение. Вопрос решен, но, возможно, не так явно, как требует аудитория. – DevNull

+0

Стандарт C - это C11, а не C99. Ответ должен процитировать из стандарта. Окончательный проект n1570 доступен бесплатно. И для обеспечения 64-битного 'int' (или наименьшего возможного типа) макрос' INT64_C' является лучшим выбором. – Olaf

 Смежные вопросы

  • Нет связанных вопросов^_^