Dividieren in GCC

Gast #178275
Hallo,
vielleicht ne blöde Frage, aber ich komm nich drauf.
Ich möchte einer Konstanten (oder auch einer Variablen) einen vom
Compiler berechneten Wert zuweisen. Leider ist mir nicht klar, wie ich
denn teilen muss, das eine float Zahl raus kommt.
Mit der normalen Division kommt ja immer nur der ganzzahlige Anteil
raus.

Beispiel:
#define ADC_REF   4920L
adc_val *= ((ADC_REF/1024);
// -> multipliziert nur mit 4
//soll aber mit 4.804 multiplizieren


Am liebsten würde ich ja schon eine Konstante ala
#define ADC_Cor  ADC_REF/1024
machen, das klappt aber auch nicht.

Bitte nicht schimpfen, ich fang gerade erst mit C an.
Gast #178276
Hm, ich hätte gedacht, daß das gar nicht erst Funktioniert, habe es aber
mal auf dem PC mit MinGW ausprobiert.

#include <stdlib.h>

#define ADC_REF 4920.0

int
main(void)
{
    printf("Value=%f\n", (ADC_REF / 1024.0));

    return 0;
}

Ergebnis:

Value=4.804688

...keine Garantie, daß das auch auf anderen Targets Funktioniert, aber
kannst es ja mal ausprobieren...
Gast #178277
Wie hier dividiert wird, hat nichts mit dem Target zu tun, sondern wie
die Konstanten definiert sind:

Werner rechnet mit int-Werten:

#define ADC_REF   4920L  (das Suffix L ist hier irrelevant)

adc_val *= ((ADC_REF/1024);

Die Klammer enthält die Division zweier Int-Werte, das wird vom
Compiler also durch einen Int-Wert ersetzt.

Der Ansatz von Oldbug rechnet mit float-Werten:

#define ADC_REF   4920.0
adc_val *= ((ADC_REF/1024.0);

Hier enthält der Ausdruck in der Klammer die Division zweier
float-Werte, die vom Compiler durch das float-Resultat ersetzt wird.


Merke: Beim Verwenden von Konstanten auf den Typ achten!#

1024 ist eine Int-Konstante,
1024.0 ist eine float-Konstante
Gast #178278
Richtig!
Aber ich war bisher der Ansicht, daß der Präprozessor "float"
überhaupt nicht unterstützt. Das ist wohl offensichtlich eine Falsche
Annahme.
Letztens haben wir darüber diskutiert, in welchem Typen der
Präprozessor überhaupt rechnet. Dabei kam von jemandem, der wohl im
"man" geblättert hat, die Aussage "HOST_LARGEST_INT", was ja
offensichtlich kein float ist.
Naja, vielleicht kann das ja jemand anders aufklären :-)
Gast #178279
Der Präprozessor macht das nicht, der rechnet nicht.
Der ist nur dafür zuständig, den Text "ADC_REF" durch den Text
"1024.0" zu ersetzen.

Das Rechnen erledigt der Compiler.
Gast #178281
Genau genommen ist "123.45" kein float, sondern ein double.
"123.45f" wäre ein float.
Compiler für Mikrocontroller scheinen aber wohl nicht zwischen double
und float zu unterscheiden (zumindest von der Datengröße, von der
Syntax her müssen sie es).
Gast #178282
Angeregt von den Beiträgen habe ich einfach mal probiert das ganze zu
casten.

#define ADC_REF    4920
#define ADC_COR  (float)ADC_REF/1024

das funktioniert auch. Die Codegröße ist identisch mit der vorher.

Danke für die Anregungen.
Werner

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.