| Автор |
Съобщение |
|
mndsl
Ранг: Новодошъл
Регистриран на: Вто Май 23, 2006 4:56 pm Мнения: 113 Местоположение: Варна
|
 Грешка при деление на 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
|
| Чет Апр 26, 2007 6:04 pm |
|
 |
|
HCL
Ранг: Форумен бог
Регистриран на: Вто Дек 14, 2004 1:31 pm Мнения: 3849
|
Какьв резултат получаваш?
И защо предаваш time като параметьр при положение, че не го ползваш преди инициализията?
|
| Чет Апр 26, 2007 6:29 pm |
|
 |
|
mndsl
Ранг: Новодошъл
Регистриран на: Вто Май 23, 2006 4:56 pm Мнения: 113 Местоположение: Варна
|
Резултата е 0xFFFFFFFE. Това което съм написал е просто за да покажа каква сметка смятам, инъче time не се променя във самата функция.
|
| Чет Апр 26, 2007 8:28 pm |
|
 |
|
Ки4о
Ранг: Форумен бог
Регистриран на: Съб Юли 22, 2006 9:50 pm Мнения: 1638
|
резултата е 2 сега го компилирах това:
time=196326;
tm=86400;
tmp=time / tm;
|
| Чет Апр 26, 2007 9:39 pm |
|
 |
|
mndsl
Ранг: Новодошъл
Регистриран на: Вто Май 23, 2006 4:56 pm Мнения: 113 Местоположение: Варна
|
Значи стигам до заключението, че това е някакъв бъг на компилатора. Тази функция не съм я променял от 1 месец и в един момент просто почна да смята грешно. Обаче понякога работи правилно. Вчера компилирах програмата и не работеше коректно. Днес компилирам същата програма без да съм я променял и работи нормално. И тъй като няма няква видима причина , реших да си заменя деленето с изваждане. Така поне работи всеки път.
|
| Пет Апр 27, 2007 9:17 am |
|
 |
|
HCL
Ранг: Форумен бог
Регистриран на: Вто Дек 14, 2004 1:31 pm Мнения: 3849
|
Голяма грешка
Защо не провериш асемблер кода, така ще се убедиш, че компилаторьт дава всеки пьт един и сьщ резултат. Тьрси грешката другаде, както писа скоро някой, компилаторьт е последната инстанция, кьдето се тьрсят грешки.
|
| Пет Апр 27, 2007 10:10 am |
|
 |
|
milenjs
Ранг: Форумен бог
Регистриран на: Сря Мар 08, 2006 2:12 pm Мнения: 2017 Местоположение: Котел
|
Мисля че колегата искаше да каже че е по скоро бъг на компилатора в резултат на неговото излекуване, не ми се вярва да е броил стотинки за оригинала 
|
| Пет Апр 27, 2007 10:17 am |
|
 |
|
mndsl
Ранг: Новодошъл
Регистриран на: Вто Май 23, 2006 4:56 pm Мнения: 113 Местоположение: Варна
|
@HCL , къде другаде да търся грешката щом всеки път компилирам едно и също и веднъж работи, веднъж не? Същия сорс, нито една буква не съм променил, снощи не искаше да работи , днес работи?!
А компилатора е кракван 
|
| Пет Апр 27, 2007 12:25 pm |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
А случайно да не ти е малко стека?
Я пробвай да го увеличиш.
А и като ползваш имитация на процесор да не искаш да кажеш че очакваш и да се държи като процесор 
|
| Пет Апр 27, 2007 1:10 pm |
|
 |
|
mndsl
Ранг: Новодошъл
Регистриран на: Вто Май 23, 2006 4:56 pm Мнения: 113 Местоположение: Варна
|
|
| Пет Апр 27, 2007 2:04 pm |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
Повече от година не съм се ровил с Hi-Tech вече нямам спомен как ставаше
По правило трябва да е в опциите на проекта. Ако не е там чети документацията на компилатора
|
| Пет Апр 27, 2007 2:26 pm |
|
 |
|
mndsl
Ранг: Новодошъл
Регистриран на: Вто Май 23, 2006 4:56 pm Мнения: 113 Местоположение: Варна
|
ОК, благодаря за инфото. Сега като се замисля може и стека да е проблема.
Edit:
 Проблема не е в стека, а в едно нещо наречено "integral promotion", което по същество прави преобразуване на типове когато сметне за необходимо. В моя случай понякога компилатора решава, че вместо да прави деленето с unsigned long ще го прави със signed long. Ето защо резултата от израза:
time=196326;
tm=86400;
tmp=time / tm;
е 0xFFFFFFFE, т.е. -2. Реално погледнато резултата е правилен, но е с обратен знак защото е signed. Решението е преобразуване на типа от израза преди присвояване, т.е.
tmp= (unsigned long)(time / tm);
И тъй като не е ясно кога компилатора ще реши да ползва нещото наречено "integral promotion", такова преобразуване според мен трябва да се прави всеки път. 
|
| Пет Апр 27, 2007 2:31 pm |
|
 |
|
bkulev
Ранг: Популярен
Регистриран на: Сря Яну 25, 2006 12:47 pm Мнения: 305 Местоположение: Varna
|
е честито, това е - сам стигна до основно правило в C styling:
Винаги преобразувай променливите явно! Никога не оставяй решението на компилатора!
т.е. винаги explicit и никога implicit, е...еее в някои случаи може, ама трябва да си абсолютно
сигурен и да знаеш, че кода няма да бъде пренасян 
|
| Пет Апр 27, 2007 4:06 pm |
|
 |
|
HCL
Ранг: Форумен бог
Регистриран на: Вто Дек 14, 2004 1:31 pm Мнения: 3849
|
Странно, в случая всички променливи са от тип unsigned long, не би трябвало да става такьв фал.
|
| Пет Апр 27, 2007 4:30 pm |
|
 |
|
bkulev
Ранг: Популярен
Регистриран на: Сря Яну 25, 2006 12:47 pm Мнения: 305 Местоположение: Varna
|
HCL прав си,
Може би проблема е в оптимизациите, които прави компилатора, кой знае 
|
| Пет Апр 27, 2007 4:41 pm |
|
|