Ответ 1
Оба делают это правильно. Выражение m * 1800
будет рассчитываться как тип int
. Если int
- 32 бита, то это будет 106200
. Если int
- 16 бит, что является вполне приемлемым способом реализации компилятора C, тогда он -24872
.
У меня есть код, который работает по-разному между GCC и Atmel Studio:
uint32_t tc = 107900;
int8_t m = 59;
tc = tc - (m*1800);
В GCC результат в tc
равен 1700, как и предполагалось.
С AtmelStudio результат в tc
равен 132772, что неверно.
Проблема заключается в том, что термин m*1800
вычисляется с ограниченной точностью m с помощью AtmelStudio.
Мой вопрос в том, компилятор делает это правильно?
Спасибо.
Оба делают это правильно. Выражение m * 1800
будет рассчитываться как тип int
. Если int
- 32 бита, то это будет 106200
. Если int
- 16 бит, что является вполне приемлемым способом реализации компилятора C, тогда он -24872
.
Кажется, что на AtmelStudio int
- 16 бит, поэтому m*1800
переполняется, вызывая поведение undefined. В вашем случае поведение, предоставленное компилятором, вероятно, было уменьшением по модулю 65536 в диапазоне [-32768,32767], что дает -24872
. Тогда tc - (m*1800)
равно 132772.
Чтобы этого избежать, вам нужно указать либо m
, либо 1800
на uint32_t
или какой-либо другой тип (например, long
), где результат не будет переполняться перед выполнением умножения.