Mit nur 2 Stellen nach Komma rechnen

Moin,
ich möchte mit nur 2 Stellen nach dem Komma eines Zwischenergebnis weiter rechnen. bekomme es nicht hin. Vielleicht kann mir jemand helfen

float ganzzahl = 0;
float ergebnis = 0;
float Winkel = 1.56212345678;
float offset = 0.12456879;


void setup() 
{
  Serial.begin(115200);
}



void loop() 
{
  ganzzahl = int((Winkel - offset) * 100) ;
  ergebnis = ganzzahl / 100;

  Serial.print("original         ");
  Serial.println(Winkel - offset,12);

  Serial.print("ganzzahl * 100   ");
  Serial.println(ganzzahl,12);
   
  Serial.print("ergebnis         ");
  Serial.println(ergebnis,12);

  Serial.println(" ");
  Serial.println(" ");
  delay(1000);
}

Ergebnis am seriellen Monitor sieht so aus:

09:59:57.890 ->
09:59:58.912 -> original 1.437554597854
09:59:58.912 -> ganzzahl * 100 143.000000000000
09:59:58.912 -> ergebnis 1.429999923706
09:59:58.912 ->

was mach ich falsch???

Gruß Stefan

Einfach gesagt, Fließkommazahlen sind ungenau und können manche Werte nicht exakt darstellen. Bei achtbittigen AVRs fällt es besonders auf.

ESP32 mit double:

original 1.437554666780
ganzzahl * 100 143.000000000000
ergebnis 1.430000000000

Der Teensy 4.1 hat eine extra Fließkommarecheneinheit. Selbst getestet habe ich die noch nicht, wird aber gerne für LED-Animationen verwendet.

und wie sieht die Lösung aus ??, welches Zahlenformat ist besser geeignet ??
Gruß Stefan

Ich hatte vergessen das ich einen UNO im Einsatz habe

Der UNO ist kein ausgesprochen guter Rechenknecht. Ich würde bei dem so weit es geht mit ganzen Zahlen rechnen und nur bei der Anzeige Fließkomma nutzen.

ESP32 mit float und Serial.println(ergebnis,2);

original 1.437554597855
ganzzahl * 100 143.000000000000
ergebnis 1.43

Winkel * 100 - offset*100 ohne den ganzen Schnodder drum rum wird dein Zwischenergebnis, welches Du dann weite rverwendest.
Ggfls. kannst auch mit 1000 rechnen. Dann aber muss die Variable zur Sicherheit uint32 werden.

welchen "Schnodder meinst du ??

ich habe mal deinen Rat zum testen übernommen, weiter bin ich damit aber nicht.

float ganzzahl = 0;
float ergebnis = 0;
float Winkel = 1.56212345678;
float offset = 0.12456879;


void setup() 
{
  Serial.begin(115200);
}

void loop() 
{
//  ganzzahl = int((Winkel - offset) * 100) ;
//  ergebnis = ganzzahl / 100;

ergebnis = Winkel * 100 - offset * 100;

  Serial.print("original         ");
  Serial.println(Winkel - offset,12);
//
//  Serial.print("ganzzahl * 100   ");
//  Serial.println(ganzzahl,12);
 
  
  Serial.print("ergebnis         ");
  Serial.println(ergebnis,12);

  Serial.println(" ");
  Serial.println(" ");
  delay(1000);
}

Ergebnis

10:36:00.397 -> original 1.437554597854
10:36:00.397 -> ergebnis 143.755462646484

Gruß Stefan

Lies bitte float Anmerkungen und Warnungen aus der Referenz.

Darstellung der Fließkomkmazahlen:

Zur Ungenauigkeit bei Fließkommazahlen: nicht alle Base2 lassen sich bruchfrei in Base10 umwandeln - da gab's in früheren Jahren (als Matheunterricht noch brauchbar war) lange Erklärungen + Übungen in der Schule.

Das Ergebnis passt doch.
Du hast nur 7 stellen Genauigkeit.
Dabei zählen die Stellen vor dem Komma mit.

Und das Ergebnis unterscheidet sich doch schon merklich von Deinem Ansatz.

Anmerkungen und Warnungen habe ich gelesen, meiner Meinung nach hab ich auch kein Problem in der Darstellung von Gleitkommazahlen .
Ich komme so nicht weiter und werde in Ruhe einen anderen Weg suchen.

Habt Dank
Stefan

Ich versteh nicht, was Du als Ergebnis haben willst!
Und: Dein Ansatz mit 12 Stellen ist auf einem 8bitter nicht umsetzbar.

letzte Mitteilung gerade erst gelesen: Mit der Lösung von dir bin ich genauso weit wie vorher. Ich müsste mit dem Ergebnis 1.43 weiter rechnen.
Gruß

Das Ergebnis von mir geteilt durch einhundert ergibt dein Original.

Willst Du nur mit 2 Stellen nach dem Komma rechnen, dann ändere den Typ Ergebnis in einen int und rechne mit 143.

Und nochmal: was ist das Ziel?

mein Ziel ist den Sinus von 1.43 zu berechnen und nicht von 1.429999999

Dann mach das doch!
Du hast die 1.43 doch auf einem Silbertablet.

Das kann jeder uC, ob 8bit oder nicht. Du brauchst halt dann double statt float und die passenden Libraries (sofern dein Compiler das nicht hinbekommt). Oder du nimmst eine lib für beliebig präzise Fließkommazahlen.

ich kann kein Silbertablett sehen. Ich brauche auch keine 12 Nachkommastellen, im Gegenteil, ich möchte das Zwischenergebnis auf 2 Stellen nach dem Komma begrenzen (nicht in der Anzeige)

eine lib für beliebig präzise Fließkommazahlen.?? wieso brauch ich einen "implementing 64-bit floating point arithmetic" lib um 1.43 duch 100 zu dividieren ? ist die Rechnung denn so exotisch??

Wie schon oben geschrieben, Flie0kommazahlen mit Base 10 sind nicht deckungsgleich mit Fließkommazahlen zur Basis 2. Warum das so ist solltest du in der Schule gelernt haben (Kapitel über Brüche und Bruchdarstellungen)

Meine schulische Laufbahn sei mal dahingestellt, da weisst du wahrscheinlich mehr als ich, aber was deine Brüche jetzt mit unterschiedlichen Zahlensystemen zu tun hat bleibt mir schleierhaft.

Deiner für mich nicht nachvollziehbaren Erklärung nach sollte ja dann folgendes auch nicht funktionieren:

float a=225;
float b;

void setup() 
{
  Serial.begin(115200);
  b=a/10;
  Serial.print("b= ");
  Serial.println(b,12);
}

void loop() {
  // put your main code here, to run repeatedly:

}

Ergebnis
15:53:14.633 -> b= 22.500000000000


Gruß Stefan