Vad gör jag fel? (GCC, double -> integer) *Felet hittat*
Vad gör jag fel? (GCC, double -> integer) *Felet hittat*
Renesas GNURX GCC, senaste version.
Håller på att lägga till en funktion till min kontorsklocka: solens upp- och nedgångstider.
Det är en rimligt brutal uträkning med en hel del sinus, cosinus, double och skit - men det kör!
Det finns bara ett ynka problem kvar: Det skiter sig!
I slutet har jag två värden i form av två double. Den ena är uppgångstiden och den andra nedgångstiden. Decimalerna är minuterna.
Men när jag (brutalt nog) gör en:
XX = Sunrise; blir det knas.
XX = integern som ska hålla timme.
Sunrise = double.
Skiten stannar här! Det finns en system-timer som fortsätter utan problem men programflödet stannar här.
Så finns det ett annat sätt att konvertera double till integer?
EDIT: Jag visste det ju egentligen - men det verkar inte finnas en funktion till detta annat än de inbyggda som aktiveras vid att man skriver Int_X = Float_X;
EDIT#2: Gjorde en workaround som ser ut till att fungera: Kollade hur många gångar det går att subtrahera 1.0 och räknade upp en int med antal gångar. Fungerar men är ju helt fel. Misstänker att det är GCC som har problem.
EDIT#3: FELET HITTAT!!! Det fanns två olika typedef av T_RISE_SET och detta gav problemet!
Håller på att lägga till en funktion till min kontorsklocka: solens upp- och nedgångstider.
Det är en rimligt brutal uträkning med en hel del sinus, cosinus, double och skit - men det kör!
Det finns bara ett ynka problem kvar: Det skiter sig!
I slutet har jag två värden i form av två double. Den ena är uppgångstiden och den andra nedgångstiden. Decimalerna är minuterna.
Men när jag (brutalt nog) gör en:
XX = Sunrise; blir det knas.
XX = integern som ska hålla timme.
Sunrise = double.
Skiten stannar här! Det finns en system-timer som fortsätter utan problem men programflödet stannar här.
Så finns det ett annat sätt att konvertera double till integer?
EDIT: Jag visste det ju egentligen - men det verkar inte finnas en funktion till detta annat än de inbyggda som aktiveras vid att man skriver Int_X = Float_X;
EDIT#2: Gjorde en workaround som ser ut till att fungera: Kollade hur många gångar det går att subtrahera 1.0 och räknade upp en int med antal gångar. Fungerar men är ju helt fel. Misstänker att det är GCC som har problem.
EDIT#3: FELET HITTAT!!! Det fanns två olika typedef av T_RISE_SET och detta gav problemet!
Senast redigerad av Icecap 25 mars 2015, 08:07:41, redigerad totalt 1 gång.
-
- Inlägg: 96
- Blev medlem: 2 februari 2011, 13:16:32
- Kontakt:
Re: Vad gör jag fel? (GCC, double -> integer)
Det är extremt osannolikt att du skulle ha hittat en bug i GCC. Särskilt för en så pass enkel grej.
Kan du slänga ihop ett minimalt exempel som uppvisar samma beteende att lägga upp?
Kan du slänga ihop ett minimalt exempel som uppvisar samma beteende att lägga upp?
Re: Vad gör jag fel? (GCC, double -> integer)
Det är extremt säkert att det är något fel! Exakt samma program fungerar klockrent under kompilern från Renesas för deras M16C-kärna.
Detta är det siste i rutinen. Den gröna LED tänds.
Kommenterar jag bort de två rader mellan LED-kommandon släcka den igen och rutinen returnerar OK.
Kod: Markera allt
... bla bla, massor av uträkningar...
Rise_Time = UT_Sun_in_south - LHA; // UTC
Set_Time = UT_Sun_in_south + LHA; // UTC
Rise_Set->Rise_Hour += TZ; // Make local time
Rise_Set->Set_Hour += TZ; // Make local time
LED_Green = true;
Rise_Set->Rise_Minute = (int)((Rise_Time - (double)Rise_Set->Rise_Hour) * 60.0); // Här kukar det ut!
Rise_Set->Set_Minute = (int)((Set_Time - (double)Rise_Set->Set_Hour) * 60.0); // Här kukar det ut!
LED_Green = false;
return(1);
Kommenterar jag bort de två rader mellan LED-kommandon släcka den igen och rutinen returnerar OK.
- Jan Almqvist
- Inlägg: 1649
- Blev medlem: 1 oktober 2013, 20:48:26
- Ort: Orust
Re: Vad gör jag fel? (GCC, double -> integer)
Har ökat den i flera steg. Ingen ändring.
Har ingen kompileringsfel, varningar eller liknande.
Har ingen kompileringsfel, varningar eller liknande.
-
- Inlägg: 1407
- Blev medlem: 29 januari 2011, 21:06:30
- Ort: Lapplandet
Re: Vad gör jag fel? (GCC, double -> integer)
Den koden ska ju rimligtvis fungera. Några gissningar till vad som skulle kunna gå fel:
* Rise_Set är inte en giltig pekare.
* Någon av Rise_Time / Set_Time / Rise_Hour / Set_Hour är NaN och du får en floating point exception vid multiplikationen. Beror på vilket FP-library du använder. Har sett både de som ger en exception och de som bara sätter resultatet till NaN.
* Bugg i floating point biblioteket. Är det hårdvaru- eller mjukvaru-FP? Testat med optimeringsflaggor av/på?
Har du möjlighet att single-steppa i en debugger och se exakt vilken instruktion som får det att stanna? Väldigt svårt att säga vad felet är annars, men rent språkmässigt är det inga fel i den koden.
* Rise_Set är inte en giltig pekare.
* Någon av Rise_Time / Set_Time / Rise_Hour / Set_Hour är NaN och du får en floating point exception vid multiplikationen. Beror på vilket FP-library du använder. Har sett både de som ger en exception och de som bara sätter resultatet till NaN.
* Bugg i floating point biblioteket. Är det hårdvaru- eller mjukvaru-FP? Testat med optimeringsflaggor av/på?
Har du möjlighet att single-steppa i en debugger och se exakt vilken instruktion som får det att stanna? Väldigt svårt att säga vad felet är annars, men rent språkmässigt är det inga fel i den koden.
Re: Vad gör jag fel? (GCC, double -> integer)
Helt utanför problemet, men skulle du inte kunna döpa om "Rise_Set" till t.ex. "Sun". Skulle bli så mycket enklare att läsa koden då. Nu är koden nästan en slumpvis kombination av "Rise_Set_Minute_Set_Rise_Set_Time_Rise_Set_Rise"
Re: Vad gör jag fel? (GCC, double -> integer)
Börja med att dela raderna så att det finns en beräkning per rad.
Prova nu med lysdioden och se var den stoppar.
Prova nu med lysdioden och se var den stoppar.
Re: Vad gör jag fel? (GCC, double -> integer)
Prova med parenteser runt pekaren innan du castar.
Kod: Markera allt
(double)(Rise_Set->Rise_Hour)
Re: Vad gör jag fel? (GCC, double -> integer)
Pointern till Rise_Set fungerar utmärkt!
MEN HALLÖJ... felet hittat! FAN alltså...
Upptäckte just att det finns (/fanns) två olika typedef av T_RISE_SET!
Den ena var med unsigned char och den andra med unsigned short.
Så tror då fan att det blev fel!!!
Nåväl, efter att ha dödad definitionen i C-filen så att det bara finns en i H-filen går den igenom programsnudden utan problem.
Har varit så fokuserat på att hitta felet i uträkningen att jag översåg en sån självklarhet.
Kod: Markera allt
typedef struct
{
unsigned short Rise_Hour, Rise_Minute;
unsigned short Set_Hour , Set_Minute;
} T_RISE_SET;
Upptäckte just att det finns (/fanns) två olika typedef av T_RISE_SET!
Den ena var med unsigned char och den andra med unsigned short.
Så tror då fan att det blev fel!!!
Nåväl, efter att ha dödad definitionen i C-filen så att det bara finns en i H-filen går den igenom programsnudden utan problem.
Har varit så fokuserat på att hitta felet i uträkningen att jag översåg en sån självklarhet.
Re: Vad gör jag fel? (GCC, double -> integer) *Felet hittat*
Borde du inte fått kompileringsvarning på det?
Re: Vad gör jag fel? (GCC, double -> integer) *Felet hittat*
Jag håller med om att det borde vara så - men suncalc.c inkluderade inte suncalc.h...