Ziffernzerlegung

float z=3.141592654;
double gz=100000000UL;
byte z1; // als Byte für den INT-Anteil
byte z2;
byte z3;
byte z4;
byte z5;
byte z6;
byte z7;

void setup() {

Serial.begin(115200);
}

void loop() {
gz=z*100000000UL;
Serial.print("gz= ");Serial.println(gz); 
z1=gz/100000000;
Serial.print("z1= ");Serial.println(z1);
z2=(gz-z1*100000000)/10000000;
Serial.print("z2= ");Serial.println(z2);
z3=(gz-z1*100000000-z2*10000000)/1000000;
Serial.print("z3= ");Serial.println(z3);
z4=(gz-z1*100000000-z2*10000000-z3*1000000)/100000;
Serial.print("z4= ");Serial.println(z4);
z5=(gz-z1*100000000-z2*10000000-z3*1000000-z4*100000)/10000;
Serial.print("z5= ");Serial.println(z5);
z6=(gz-z1*100000000-z2*10000000-z3*1000000-z4*100000-z5*10000)/1000;
Serial.print("z6= ");Serial.println(z6);

while(1);
}

Ich will eine Zahl (PI nur als Beispiel aber ähnlich) in ihre einzelnen Ziffern zerlegen. Bis z5 läuft alles wunschgemäß. z6 gibt mir 74 aus. Warum?
Grüße Thomas

1 Like

Achtung.
Auf 8Bit Systemen wie Arduino mit 4 Byte Fließkommazahl hat die Fleißkommazahl nur 6 bis 7 signifikante Ziffern. Also alles was nach 3,14159 bzw 92 kommt sind reine Hausnummern.
Das ist dann egal ob die Zahl Pi, e, oder sonst eine Konstante oder eine selbst erfundene oder errechnete Zahl ist.
Ich weiß nicht ob das der Grund Deines komischen Effektes ist, könne mir es aber vorstellen.

Oder hab ich das jetzt falsch interpretiert? :wink:

Grüße Uwe

VIELEN(!) Herzlichen Dank für diese Aufgabe.
Endlich jemand, der das zur Diskussion stellt.

Herkunft:
https://www.arduinoforum.de/code-referenz

Oder wo auch immer float behandelt wird.

Jetzt, wo du es sagst (schreibst)... da war was, richtig.

Danke für den Tip.
Auf einem DUE macht er so in etwa er soll:
21:24:11.953 -> gz= 314159264.00
21:24:11.953 -> z1= 3
21:24:11.953 -> z2= 1
21:24:11.953 -> z3= 4
21:24:11.953 -> z4= 1
21:24:11.953 -> z5= 5
21:24:11.953 -> z6= 9
21:24:11.953 -> z7= 2
21:24:11.953 -> z8= 6
21:24:11.953 -> z9= 4
Allerdings passt die '4' am Ende nicht so ganz

Wenn Du was mit Fließkomma machen willst, es gibt auch µCs mit Fließkommarecheneinheit wie z. B. beim Teensy 4.1. Eigene Erfahrungen habe ich damit aber nicht, daher nur ein Hinweis, keine Enpfehlung.

Eigentlich wollte ich einen STM32 nehmen, aber die haben alle irgendwelche Treiberprobleme

Ich schrieb ja 8 Bit Controller. ( extra damit mir niemand einen Einwand geben konnte).
32 Bit Kontroller können eine Fleißkommazahl ruhig mit einer anderen Anzahl von byte darstellen und darum können die Signifikanten Ziffern anders als bei einem UNO sein.
Grüße Uwe

Das ist doch wurscht.
Verzichte auf float.
Trenne Deine Zahl in Vorkamma und Nachkomma ODER mach daraus ein CharArray.
Du willst die einzelnen Ziffern haben - dafür ist das letztere die allerbeste Variante!

@MicroBahner kennt sich mit STM32 aus, eventuell nicht mit Fließkomma, aber mit Treibern, den könntest Du mal fragen.

'STM32' ist ein sehr breites Feld, da solltest Du mal konkreter sagen, wo Du Probleme hast.

Ich hab den F103 (Blue Pill) und dieser wird von Windows10 nicht erkannt. "USB-Gerät wurde nicht erkannt". Das Ganze auf 3 Rechnern und 2 Boards, so das ich nicht an einen Defekt glaube, zumal es schonmal funktioniert hat.

GRMPF!
Kann das abgetrennt werden?

Mit dem Core von Roger Clark, und dem dort mitgelieferten Bootloader (den man natürlich erstmal auf das Board flashen muss) funktioniert das bei mir einwandfrei. Ohne Bootloader geht es mit einem STLink auch.

Ich sehe es morgen an, danke

Da mein Hinweis verpufft ist, hier dann mal meine Vorgabe:

float unbestimmteZahl = 3.141692654;
float neueUnbestimmteZahl = 3141592654.00;
char unbestimmteZeichenketteNachKomma[] = "3.1415926540";
char unbestimmteZeichenketteVorKomma[]  = "314159265.358979328462";
char myBuffer[23] = {0};


void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  Serial.print(F("Ausgabe von unbestimmte Zahl: "));
  Serial.println(unbestimmteZahl);
  Serial.print(F("Ausgabe von float unbestimmte Zahl in char: "));
  dtostrf(unbestimmteZahl, 12, 10, &myBuffer[strlen(myBuffer)]);
  tiktak();
  memset(myBuffer, 0, sizeof(myBuffer));
  Serial.print(F("Ausgabe von float neuer unbestimmte Zahl in char: "));
  dtostrf(neueUnbestimmteZahl, 12, 10, &myBuffer[strlen(myBuffer)]);
  tiktak();
  memset(myBuffer, 0, sizeof(myBuffer));
  memcpy(myBuffer, unbestimmteZeichenketteNachKomma, sizeof(unbestimmteZeichenketteNachKomma));
  Serial.print(F("Ausgabe von Zahl in Nachkomma @ char: "));
  tiktak();
  memset(myBuffer, 0, sizeof(myBuffer));
  memcpy(myBuffer, unbestimmteZeichenketteVorKomma, sizeof(unbestimmteZeichenketteVorKomma));
  Serial.print(F("Ausgabe von Zahl in Vorkomma @ char: "));
  tiktak();
}

void loop()
{
}

void tiktak()
{
  Serial.println();
  Serial.println(myBuffer);
  for (unsigned int i = 0; i < sizeof(myBuffer); i++ )
  {
    Serial.println(myBuffer[i]);
  }
}

Edit-1 und 2
Mein Versuch:
Ausgabe auf dem SerMon: - ist hier nicht darstellbar.

Danke für deine Mühe, dass funktioniert.
Das meins nicht funktioniert hat, lag an der "8-Bit Falle"