- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 17

Thema: int Variable, Grenzbereiche

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    int Bsp5 = 3/2*2; // wir 3 gespeichert?
    Sicher? Sollte 2 sein, nicht 3.

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.04.2015
    Beiträge
    903
    Zitat Zitat von Sisor Beitrag anzeigen
    Sicher? Sollte 2 sein, nicht 3.
    Vorsicht!
    Die Auflösung des Literals wird vom Precompiler übernommen.
    Für das Fragment:
    int main (void)
    {

    int8_t test = 3.1415/2 *2;
    if (test == 3)
    SetLED2();

    bekomme ich vom Compiler im AVR-GCC weder eine Warnung, noch einen Fehler. Im Listing sehe ich aber:

    000028b6 <main>:
    static inline void SetLED2()
    {
    PORTD.OUTSET = 0x02; }
    28b6: c0 e6 ldi r28, 0x60 ; 96
    28b8: d6 e0 ldi r29, 0x06 ; 6
    28ba: 12 e0 ldi r17, 0x02 ; 2
    28bc: 1d 83 std Y+5, r17 ; 0x05

    Da wird also weder eine Variable angelegt, noch im ganzzahligen Bereich, wie auf der eigentlichen Maschine, gerechnet.
    Insofern sind die oben angegebenen Beispielzeilen nicht wirklich tauglich, die Sache zu durchschauen.

    Besser (so, wie erwartet) wird's mit:
    int main (void)
    {
    int8_t test = 3.1415;
    test/=2;
    test*=2;
    if (test == 3)
    SetLED2();

    Hier castet sich der fraktale Anteil im Precompiler weg:
    test = 3.1415 ->3
    test /= 2 ->1
    test *= 2 ->2

    Es wird vom Compiler im Listing zwar immer noch keine Variable angelegt, aber der Aufruf von SetLED2() kommt auch nicht mehr.
    Geändert von Holomino (09.05.2020 um 15:43 Uhr)

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Zitat Zitat von Holomino Beitrag anzeigen
    Vorsicht!
    Die Auflösung des Literals wird vom Precompiler übernommen.
    Für das Fragment:
    int main (void)
    {

    int8_t test = 3.1415/2 *2;
    if (test == 3)
    SetLED2();

    bekomme ich vom Compiler im AVR-GCC weder eine Warnung, noch einen Fehler. Im Listing sehe ich aber:

    000028b6 <main>:
    static inline void SetLED2()
    {
    PORTD.OUTSET = 0x02; }
    28b6: c0 e6 ldi r28, 0x60 ; 96
    28b8: d6 e0 ldi r29, 0x06 ; 6
    28ba: 12 e0 ldi r17, 0x02 ; 2
    28bc: 1d 83 std Y+5, r17 ; 0x05

    Da wird also weder eine Variable angelegt, noch im ganzzahligen Bereich, wie auf der eigentlichen Maschine, gerechnet.
    Insofern sind die oben angegebenen Beispielzeilen nicht wirklich tauglich, die Sache zu durchschauen.

    Besser (so, wie erwartet) wird's mit:
    int main (void)
    {
    int8_t test = 3.1415;
    test/=2;
    test*=2;
    if (test == 3)
    SetLED2();

    Hier castet sich der fraktale Anteil im Precompiler weg:
    test = 3.1415 ->3
    test /= 2 ->1
    test *= 2 ->2

    Es wird vom Compiler im Listing zwar immer noch keine Variable angelegt, aber der Aufruf von SetLED2() kommt auch nicht mehr.
    Wenn du mit Precompiler Präprozessor meinst, der rechnet nicht. GCC hat keinen Precompiler für C/C++. Die Auswertung der Literale erfolgt im Compiler.
    Bei int t = 3.1415/2 *2 ist 3.1415 ein float und 2 ein int, damit ist das Ergebnis aus 3.1415/2 ein float, damit ist das 3.1415/2 * 2 auch ein float. Das wird dann zum int (3) gecastet.
    Bei int u = 3/2 *2 sind 3 und 2 int, damit ist 3/2 ein int (1), damit ist 1*2 ein int (2). Das braucht nicht mehr gecastet werden.

    Regeln-fuer-Konvertierungen-und-Casts

  4. #4
    HaWe
    Gast
    Zitat Zitat von Sisor Beitrag anzeigen
    Sicher? Sollte 2 sein, nicht 3.
    ja, stimmt ntl!

    Code:
    void setup() {
      Serial.begin(115200);
      delay(1000);
      Serial.println();
    
      
      int x=3;
      int y=2;
      int z=2;
      
      int Bsp5 = 3/2*2;
      Serial.println(Bsp5);
      
      Bsp5 = x/y*z;
      Serial.println(Bsp5);
      
    }
    
    void loop() {
      
    
    }
    output:

    2
    2
    edit: sollte durchgestrichen sein, aber Durchstreichfunktion existiert hier nicht: [s]da es alles Konstanten sind, wird die "Berechnung" evtl vom Preprozessor erledigt, ohne Compiler[/s]

    Aber auch mit volatile int kommt erwartungsgemäß dasselbe Ergebnis.

    Code:
    void setup() {
      Serial.begin(115200);
      delay(1000);
      Serial.println();
    
      
      volatile int x=3;
      volatile int y=2;
      volatile int z=2;
      
      volatile int Bsp5 = 3/2*2;
      Serial.println(Bsp5);
      
      Bsp5 = x/y*z;
      Serial.println(Bsp5);
      
    }
    
    void loop() {
      
    
    }
    Geändert von HaWe (10.05.2020 um 14:57 Uhr)

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Der Präprozessor rechnet nicht. Er bearbeitet Anweisungen zum Einfügen von Quelltext (#include), zum Ersetzen von Makros (#define), und bedingter Übersetzung (#if).
    Code:
    #define CELSIUS_ZU_FAHRENHEIT( t ) ( ( t ) * 1.8 + 32 )
    Das Makro CELSIUS_ZU_FAHRENHEIT beschreibt die Umrechnung einer Temperatur (angegeben als Parameter t) aus der Celsius- in die Fahrenheit-Skala. Auch ein Makro mit Parametern wird im Quelltext ersetzt:

    Code:
    int fahrenheit, celsius = 10;
    fahrenheit = CELSIUS_ZU_FAHRENHEIT( celsius + 5 );
    wird durch den C-Präprozessor ersetzt zu:
    Code:
    int fahrenheit, celsius = 10;
    fahrenheit = ( ( celsius + 5 ) * 1.8 + 32 );
    Quelle
    Danach darf der Compiler gemäß der spezifizierten Rechenregeln weitermachen.

  6. #6
    HaWe
    Gast
    Zitat Zitat von Sisor Beitrag anzeigen
    Der Präprozessor rechnet nicht.
    danke, da war ich einem Irrtum aufgesessen, ich dachte wirklich dass er bereits bei konstanten Ausdrücken wie
    3/2*2
    quasi das konstante Zwischenergebnis einsetzt - tut also doch immer erst hinterher der Compiler.

Ähnliche Themen

  1. Variable auf LCD ausgeben
    Von Haveaniceday im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 20.07.2017, 18:57
  2. [ERLEDIGT] C++ Hinweis: variable 'pHelp' set but not used [-Wunused-but-set-variable]
    Von geWichtig im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 20.02.2017, 15:09
  3. Komplexe Variable
    Von DanielSan im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 19.06.2011, 14:30
  4. if Variable > 1 then Variable + 1
    Von klaus1973 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 26.11.2005, 14:31
  5. Pin mit Variable vergleichen
    Von Kundesbanzler im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 23.02.2005, 14:58

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test