Sida 1 av 1

Vad gör jag fel? (GCC, double -> integer) *Felet hittat*

Postat: 24 mars 2015, 19:48:10
av Icecap
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!

Re: Vad gör jag fel? (GCC, double -> integer)

Postat: 24 mars 2015, 21:21:26
av thomasloven
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?

Re: Vad gör jag fel? (GCC, double -> integer)

Postat: 24 mars 2015, 21:50:30
av Icecap
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.

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);
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.

Re: Vad gör jag fel? (GCC, double -> integer)

Postat: 24 mars 2015, 22:06:51
av Jan Almqvist
För liten stack?

Re: Vad gör jag fel? (GCC, double -> integer)

Postat: 24 mars 2015, 22:10:39
av Icecap
Har ökat den i flera steg. Ingen ändring.

Har ingen kompileringsfel, varningar eller liknande.

Re: Vad gör jag fel? (GCC, double -> integer)

Postat: 25 mars 2015, 00:38:03
av Mr Andersson
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.

Re: Vad gör jag fel? (GCC, double -> integer)

Postat: 25 mars 2015, 01:19:44
av bearing
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)

Postat: 25 mars 2015, 03:08:38
av baron3d
Börja med att dela raderna så att det finns en beräkning per rad.
Prova nu med lysdioden och se var den stoppar.

Re: Vad gör jag fel? (GCC, double -> integer)

Postat: 25 mars 2015, 07:43:20
av bit96
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)

Postat: 25 mars 2015, 08:06:13
av Icecap
Pointern till Rise_Set fungerar utmärkt!

Kod: Markera allt

typedef struct
  {
  unsigned short Rise_Hour, Rise_Minute;
  unsigned short Set_Hour , Set_Minute;
  } T_RISE_SET;
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.

Re: Vad gör jag fel? (GCC, double -> integer) *Felet hittat*

Postat: 25 mars 2015, 08:20:12
av Nerre
Borde du inte fått kompileringsvarning på det?

Re: Vad gör jag fel? (GCC, double -> integer) *Felet hittat*

Postat: 25 mars 2015, 08:45:50
av Icecap
Jag håller med om att det borde vara så - men suncalc.c inkluderade inte suncalc.h...