Forum: Compiler & IDEs Falscher Rückgabewert bei float Rückgabe


von Klaus (Gast)


Lesenswert?

Hallo,
ich habe das Problem, dass meine Funktion sobald ein float oder double 
Wert zurückgegeben wird falsche Werte liefert.
1
int main(void)
2
{
3
  float temperatur;
4
5
  temperatur = read_temperature();
6
}
7
8
float read_temperature(uint8_t id)
9
{
10
  //do something
11
  temperatur *= 0.0625;
12
  return temperatur
13
}
Das liefert mir eine Temperatur 16807.

Änder ich das ganze zu bekomme ich die richtigen Werte...
1
int main(void)
2
{
3
  float temperatur;
4
  uint16_t buffer;
5
6
  buffer = read_temperature();
7
  temperatur = buffer*0.0625;
8
}
9
10
uint16_t read_temperature(uint8_t id)
11
{
12
  //do something
13
  return temperatur
14
}

Vielen Dank für eure Hilfe!

von Peter II (Gast)


Lesenswert?

Klaus schrieb:
> Das liefert mir eine Temperatur 16807.

und welchen DatenType hat temperatur in

float read_temperature

bitte etwas mehr code zeigen, mit diesen kann man die werte nicht 
nachvollziehen weil man nicht weiss auf was temperatur gesetzt ist.

von (prx) A. K. (prx)


Lesenswert?

Hast du Warnungen des Compilers ignoriert? Nimm mal -Wall rein (wenn 
GCC). Wass passiert, wenn du die Reihenfolge der Funktionen umkehrst?

von Ronny S. (duselbaer)


Lesenswert?

Das read_temperature in deinem Code erwartet einen Parameter, beim 
Aufruf gibst Du keinen mit. Ist das nur ein Copy&Paste Fehler, oder ist 
das auch in deinem Code so?

von Klaus (Gast)


Lesenswert?

Kann auch gerne die Funktion posten, dachte es ist so übersichtlicher.
1
float ow_read_temperature(uint8_t id)
2
{
3
  uint8_t i;
4
  uint8_t scratchpad[9]; //datenpuffer für auslesen des scratchpads
5
  float temperatur;
6
  
7
  // Start mit Master-Reset-Impuls u. Abfrage: Slave presence
8
  if(ow_reset())
9
  {
10
    return 0;
11
  }
12
  
13
  //Slave anwählen
14
  ow_match(id);
15
  
16
  // Abfrage-Befehl senden: "READ SCRATCHPAD" = 0xBE
17
  ow_wr_byte(0xbe);
18
19
  for (i=0; i<9; i++)
20
  {
21
    scratchpad[i] = ow_rd_byte();
22
  }
23
  
24
  if((scratchpad[1] & 0xF8) == 0x00) //Wenn sign bit == 0 -> positive temperatur
25
  {
26
    temperatur = ((scratchpad[1]<<8)+scratchpad[0]);
27
    temperatur *= 0.0625;
28
    return temperatur;
29
  }
30
  else
31
  {
32
    return 0; //Fehler
33
  }

von Klaus (Gast)


Lesenswert?

Das mit dem Übergabeparameter ist ein Tippfehler das ist im Code 
richtig.

von Klaus (Gast)


Lesenswert?

Jetzt funktioniert es. "Umdrehen" ging zwar nicht da in anderer c-Datei, 
ein extern float ow_read_temperature(uint8_t id) hat aber geholfen. 
Blöder Fehler.
Kann mir jetzt aber einer erklären warum es bei einem uint16_t 
Rückgabewert trotzdem funktioniert bei einem float jedoch nicht?

von (prx) A. K. (prx)


Lesenswert?

Klaus schrieb:
> Kann mir jetzt aber einer erklären warum es bei einem uint16_t
> Rückgabewert trotzdem funktioniert bei einem float jedoch nicht?

Weil in uralter K&R-Tradition unbekannte Funktionen ein int als 
Rückgabewert haben. Der ist uint16_t hinreichend ähnlich.

von Karl H. (kbuchegg)


Lesenswert?

Klaus schrieb:
> Jetzt funktioniert es. "Umdrehen" ging zwar nicht da in anderer c-Datei,
> ein extern float ow_read_temperature(uint8_t id) hat aber geholfen.
> Blöder Fehler.
> Kann mir jetzt aber einer erklären warum es bei einem uint16_t
> Rückgabewert trotzdem funktioniert bei einem float jedoch nicht?

Weil der Compiler bei allem was er nicht kennt Standardannahmen trifft. 
Und die lauten in deinem Fall:

Eine Funktion von der nichts bekannt ist, liefert einen int zurück.

Wenn das das komplette Programm ist
1
int main()
2
{
3
  double j;
4
5
  j = cos( 0.5 );
6
}

dann weiß der Compiler an dieser Stelle nichts von einer Funktion namens 
'cos'. Also gelten Standardannahmen. Zwei davon sind
* da du ein Argument benutzt und dieses Argument (0.5) den Datentyp 
double hat, vertrau ich meinem Progrtammierer und die Funktion cos wird 
angenommen als eine Funktion, die genau 1 Argument nimmt und dieses muss 
double sein
* da über den Datentyp des Returnwertes nichts bekannt ist, wird 
angenommen, dass die Funktion einen int zurückliefert.

Jetzt ...
1
double cos( double angle );
2
3
int main()
4
{
5
  double j;
6
7
  j = cos( 0.5 );
8
}
... sieht die Sache anders aus. Jetzt informiert der Prototyp der 
Funktion den Compiler darüber, wie sich die Sache mit der Funktion 'cos' 
wirklich verhält.

Steht denn diese 'implizit-int' Regel in den heutigen C-Büchern nicht 
mher drinnen? Dabei ist sie samt den Promotion Regeln so dermassen 
wichtig. Wie will man den anders verstehen, wie sich die 
Argumentübergabe bei variadischen Funktionen verhält? Oder hast du gar 
kein C-Buch? Gefährlich!

von Klaus (Gast)


Lesenswert?

Danke, dass du dir die Mühe gemacht hast.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.