#1 2017-03-05 10:45:11

Andrii
Учасник
Зареєстрований: 2017-03-05
Повідомлень: 2

Баг процессора ?

Всем доброго дня!

Arduino Mega2650 rev3 (clone)

Натолкнулся на такую штуку: не правильно умножает. Вынес в отдельный скетч. Подтвердилось. Прошу проверить на своих девайсах.

void setup() {
  Serial.begin(9600);
  long t=200*100*4;
  Serial.println(t);
  t=80000;
  Serial.println(t);
}

void loop() {
}

На сериал-мониторе:
14464
80000

Бред. Или баг.

Остання редакція Andrii (2017-03-05 10:45:33)

Неактивний

#2 2017-03-05 10:58:15

Andrii
Учасник
Зареєстрований: 2017-03-05
Повідомлень: 2

Re: Баг процессора ?

Сори, погорячился.
Правильный ответ:

long t = 200 * 100 *2L;

Компилер не смотря на тип переменной приемника значения не понимает и вычисляет промежуточные значения как 16-битные, в результате переполнение и остаток как результат.

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

Остання редакція Andrii (2017-03-05 11:00:23)

Неактивний

#3 2018-05-15 19:04:01

sslobodyan
Гість

Re: Баг процессора ?

В случае смешивания типов операндов всегда явно прописывайте в каком формате проводить вычисление:

long res = (float) 10 / 3 * 1000;

Компилятор по первому операнду определяет к какому типу приводить все операнды. В данном случае все приводим к флоату, поэтому получаем 3333. Без указания (float) получили бы 3000, потому что 10 поделилось бы на 3 как целое, получили 3 и умножив на 1000 результат 3000.

#4 2018-05-15 19:43:43

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Баг процессора ?

Andrii пише:

Бред. Или баг.

Бардак в прочтении стандартов. По уму вы написали правильно. У GCC еще и не такие фокусы бывают. Константные операции по умолчанию должны быть типа int, длинные нужно объявлять явно.  ISO/IEC 9899:201x Committee Draft — April 12, 2011 N1570 6.6 Constant expressions

Неактивний

#5 2018-05-16 17:08:34

Green
Учасник
Зареєстрований: 2015-11-08
Повідомлень: 593

Re: Баг процессора ?

По уму != по стандарту. Ибо умы у всех разные.)
Как я понимаю 200 * 100 * 4 = 80000, но т.к. операнды int, то и результат с учётом переполнения будет 14464 (+ 65536).
Если один из операндов будет с типом L, то и результат будет правильным. Не?

Неактивний

#6 2018-05-16 17:13:19

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Баг процессора ?

Green пише:

Если один из операндов будет с типом L, то и результат будет правильным. Не?

Ну да! И это не логично, но так есть. Для совместимости снизу вверх, наверное.

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму