Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Грешка при деление на long с long
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=4113
Страница 1 от 3

Автор:  mndsl [ Чет Апр 26, 2007 6:04 pm ]
Заглавие:  Грешка при деление на long с long

Ето това не смята вярно и това е!

void ToTime(unsigned long time,char * totimef)
{
unsigned char hours,mins,secs;
unsigned int days;
unsigned long tmp;
unsigned long tm;

time=196326;
tm=86400;
tmp=time / tm; <- резултата от този ред не е това което трябва да е.
...
...
}

Компилатора е Hi-Tech PICC18 9.50

Автор:  HCL [ Чет Апр 26, 2007 6:29 pm ]
Заглавие: 

Какьв резултат получаваш?
И защо предаваш time като параметьр при положение, че не го ползваш преди инициализията?

Автор:  mndsl [ Чет Апр 26, 2007 8:28 pm ]
Заглавие: 

Резултата е 0xFFFFFFFE. Това което съм написал е просто за да покажа каква сметка смятам, инъче time не се променя във самата функция.

Автор:  Ки4о [ Чет Апр 26, 2007 9:39 pm ]
Заглавие: 

резултата е 2 сега го компилирах това:
time=196326;
tm=86400;
tmp=time / tm;

Автор:  mndsl [ Пет Апр 27, 2007 9:17 am ]
Заглавие: 

Значи стигам до заключението, че това е някакъв бъг на компилатора. Тази функция не съм я променял от 1 месец и в един момент просто почна да смята грешно. Обаче понякога работи правилно. Вчера компилирах програмата и не работеше коректно. Днес компилирам същата програма без да съм я променял и работи нормално. И тъй като няма няква видима причина , реших да си заменя деленето с изваждане. Така поне работи всеки път.

Автор:  HCL [ Пет Апр 27, 2007 10:10 am ]
Заглавие: 

mndsl написа:
Значи стигам до заключението, че това е някакъв бъг на компилатора.

Голяма грешка :)
Защо не провериш асемблер кода, така ще се убедиш, че компилаторьт дава всеки пьт един и сьщ резултат. Тьрси грешката другаде, както писа скоро някой, компилаторьт е последната инстанция, кьдето се тьрсят грешки.

Автор:  milenjs [ Пет Апр 27, 2007 10:17 am ]
Заглавие: 

Мисля че колегата искаше да каже че е по скоро бъг на компилатора в резултат на неговото излекуване, не ми се вярва да е броил стотинки за оригинала :D

Автор:  mndsl [ Пет Апр 27, 2007 12:25 pm ]
Заглавие: 

@HCL , къде другаде да търся грешката щом всеки път компилирам едно и също и веднъж работи, веднъж не? Същия сорс, нито една буква не съм променил, снощи не искаше да работи , днес работи?! :?

А компилатора е кракван :)

Автор:  Nikola Kirov [ Пет Апр 27, 2007 1:10 pm ]
Заглавие: 

А случайно да не ти е малко стека?
Я пробвай да го увеличиш.

А и като ползваш имитация на процесор да не искаш да кажеш че очакваш и да се държи като процесор :)

Автор:  mndsl [ Пет Апр 27, 2007 2:04 pm ]
Заглавие: 

Nikola Kirov написа:
А случайно да не ти е малко стека?
Я пробвай да го увеличиш.


Я кажи как.

Автор:  Nikola Kirov [ Пет Апр 27, 2007 2:26 pm ]
Заглавие: 

Повече от година не съм се ровил с Hi-Tech вече нямам спомен как ставаше :(
По правило трябва да е в опциите на проекта. Ако не е там чети документацията на компилатора

Автор:  mndsl [ Пет Апр 27, 2007 2:31 pm ]
Заглавие: 

ОК, благодаря за инфото. Сега като се замисля може и стека да е проблема.

Edit:
:idea: Проблема не е в стека, а в едно нещо наречено "integral promotion", което по същество прави преобразуване на типове когато сметне за необходимо. В моя случай понякога компилатора решава, че вместо да прави деленето с unsigned long ще го прави със signed long. Ето защо резултата от израза:

time=196326;
tm=86400;
tmp=time / tm;

е 0xFFFFFFFE, т.е. -2. Реално погледнато резултата е правилен, но е с обратен знак защото е signed. Решението е преобразуване на типа от израза преди присвояване, т.е.

tmp=(unsigned long)(time / tm);

И тъй като не е ясно кога компилатора ще реши да ползва нещото наречено "integral promotion", такова преобразуване според мен трябва да се прави всеки път. :!:

Автор:  bkulev [ Пет Апр 27, 2007 4:06 pm ]
Заглавие: 

е честито, това е - сам стигна до основно правило в C styling:

Винаги преобразувай променливите явно! Никога не оставяй решението на компилатора!
т.е. винаги explicit и никога implicit, е...еее в някои случаи може, ама трябва да си абсолютно
сигурен и да знаеш, че кода няма да бъде пренасян :)

Автор:  HCL [ Пет Апр 27, 2007 4:30 pm ]
Заглавие: 

Странно, в случая всички променливи са от тип unsigned long, не би трябвало да става такьв фал.

Автор:  bkulev [ Пет Апр 27, 2007 4:41 pm ]
Заглавие: 

HCL прав си,

Може би проблема е в оптимизациите, които прави компилатора, кой знае :(

Страница 1 от 3 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/