Прикольная штука!
От: NewKent  
Дата: 03.11.03 16:07
Оценка:
Правильные варианты:

short int *smoothedim;
unsigned char **edge;
int rows, int cols;
int i;

for(i = 0;i< rows*cols;i++){
   (*edge)[i] = (255*smoothedim[i]/255);
}


for(i = 0;i< rows*cols;i++){
   (*edge)[i] = (smoothedim[i]/1);
}



Не правильный варианты (с точки зрения компилятора)


for(i = 0;i< rows*cols;i++){
   (*edge)[i] = (smoothedim[i]/255*255);
}


for(i = 0;i< rows*cols;i++){
   (*edge)[i] = (smoothedim[i]/255*255);
}


Причем, второй вариант не трактуется как (*edge)[i] = (smoothedim[i]/(255*255));

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

Испытано на VC6, VC6+SP5, VC7.

Я просто в шоке...
Re: Прикольная штука!
От: Аноним  
Дата: 03.11.03 16:13
Оценка:
Здравствуйте, NewKent, Вы писали:

NK>Я просто в шоке...


А на самом деле в целочисленной арифметике Си тождество a * b / b == a / b * b не гарантируется.
Re: Прикольная штука!
От: Андрей Тарасевич Беларусь  
Дата: 03.11.03 18:44
Оценка: +1
Здравствуйте, NewKent, Вы писали:

NK>Не правильный варианты (с точки зрения компилятора)


NK>
NK>for(i = 0;i< rows*cols;i++){
NK>   (*edge)[i] = (smoothedim[i]/255*255);
NK>}
NK>


NK>
NK>for(i = 0;i< rows*cols;i++){
NK>   (*edge)[i] = (smoothedim[i]/255*255);
NK>}
NK>


Не совсем понимаю. В чем же заключается разница между этими двумя "неправильными вариантами"? Почему уж тогда не три или четыре?

NK>Причем, второй вариант не трактуется как (*edge)[i] = (smoothedim[i]/(255*255));


Разумеется, не трактуется. С чего бы это вдруг ему так трактоваться?

NK>Разница между "правильным" и "неправильным" заключается в массиве edge. В случае неправильного варианта, данные дублируются со смещением, и, вообще, чего-то страшное.


По прежнему не понимаю, что ты увидел здесь "неправильного". Надеюсь, ты понимаешь, что в С/С++, например, '10 * 255 / 255' дает '10', в то время как '10 / 255 * 255' дает '0' (как и должно быть)?

NK>Испытано на VC6, VC6+SP5, VC7.

NK>Я просто в шоке...

Best regards,
Андрей Тарасевич
Re: Прикольная штука!
От: Кодт Россия  
Дата: 04.11.03 08:23
Оценка:
Здравствуйте, NewKent, Вы писали:

NK>Я просто в шоке...


Ошибки целочисленного округления в кольце по модулю 2^16.

(x * 1) = x
(x / 255) * 255 = x — (x % 255)
(x * 255) / 255 = (x < 256) ? x : x — 65536

Последнее — связано с тем, что выражение (255*(short)x) == (short)(255*x),
(short)y = (y + 32768) % 65536 — 32768
Перекуём баги на фичи!
Re[2]: Прикольная штука!
От: Кодт Россия  
Дата: 04.11.03 08:27
Оценка:
К>Ошибки целочисленного округления в кольце по модулю 2^16.

То есть ошибками это назвать сложно — это dura lex sed lex (закон дурак, но это закон ).

Два феномена: деление нацело (с отбрасыванием остатка) и умножение по модулю.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.