Go Down

Topic: Funktioniert der Datentyp "long long" in der Arduino IDE ?  (Read 2116 times) previous topic - next topic

rudirabbit

Hallo,
Ich bräuchte zwecks Rechnungen am Kreis einen Datentyp der größer als 32Bit ist, unsigned long reicht in bestimmen Fällen nicht aus.

Der Compiler akzeptiert long long zwar, habe aber den Eindruck das es nur ein long ist.  :smiley-evil:

Konkret habe ich dieses Problem:
Mein Code vearbeitet G-Code, mein "Maschinchen" macht meist alles richtig.
Kommt jedoch sowas, kommt es zum Problem.
z.b.
Code: [Select]

G03 X25.8901 Y23.9794 I-159.6892 J4.3159

Dies soll einen Kreisbogen gegen den Uhrzeigensinn fahren.
Von der aktuellen Position liegt der X Mittelpunkt  -159.6..mm  links davon und +4.31..mm in Y Richtung. 
Der Parameter von Millimeter auf die Steps der Motoren beträgt 512.

Dadurch entstehen recht große Zahlenwerte, zum Berechnen des Radius beträgt das Quadrat der X Richtung in diesem Beispiel 6627262464 ! 

Denke ich brauche einen anderen Ansatz des Problems, Bresenham braucht aber erst mal den Radius um zu arbeiten wenn ich richtig liege. 

Wie schon gesagt mein Programm läuft im Prinzip gut, nur wenn bei solchen Zeilen die Variaben überlaufen kommt es zum Gau.
Der G-Code kommt von dem Inkscape G-Code Plugin und der G-Simulator zeigt das der Code schon richtig ist.
Arduino UNO,MEGA,DUE 
Dunkel die andere Seite ist. - Klappe, Yoda, und iss deinen Toast :-)

michael_x

nach
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ganzzahlige_Datentypen_.28Integer.29
sollte int64_t möglich sein...

Serenifly

Ausprobiert habe ich es nicht, aber ich habe mal gelesen dass dadurch die Code-Größe merkbar ansteigt. Aber theoretisch sollte es gehen.

jurs

Dadurch entstehen recht große Zahlenwerte, zum Berechnen des Radius beträgt das Quadrat der X Richtung in diesem Beispiel 6627262464 !  
Solche "kleinen" Zahlen sind für "long long" überhaupt kein Problem, egal ob signed oder unsigned.

Aber sobald irgendwo bei Deinen Rechnungen 'float' ins Spiel kommt, z.B. weil Du eine math-Funktion aufrufst, die einen 'float' Parameter verarbeitet und/oder einen 'float' Rückgabewert liefert, ist das Ergebnis sofort auf die typische Ungenauigkeit von float runtergestrubbelt, also "ca. 6-7 signifikante Stellen".

Eine Genauigkeit von 10 signifikanten Stellen kannst Du selbstverständlich nur dann erreichen, wenn in der gesamten Rechnung niemals auch nur irgendeine Funktion mit 'float' rechnet.

Doc_Arduino

Hallo,

dazu fällt mir was ein. Wenn 64Bit Zahlen möglich sind, warum wird dann zum Bsp. mit millis() damit nicht gerechnet? Dann hätte man in seinem Leben keinen Überlauf mehr. Denn das würde für 584.942.417 Jahre reichen.  :)
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

sschultewolter

Weil es mehr Speicher braucht und vollkommen unnötig ist, wenn man die Zeiten nicht über 40 Tage hinweg vergleichen muss.

Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

rudirabbit

Quote
Aber sobald irgendwo bei Deinen Rechnungen 'float' ins Spiel kommt, z.B. weil Du eine math-Funktion aufrufst, die einen 'float' Parameter verarbeitet und/oder einen 'float' Rückgabewert liefert, ist das Ergebnis sofort auf die typische Ungenauigkeit von float runtergestrubbelt, also "ca. 6-7 signifikante Stellen".
So ist es, ich hatte seltsame Ergebnisse mit pow(x,2) die ich nicht erklären konnte.
Ist nichts anderes als  x*x ergibt aber andere Ergebnisse.
Die Quadratwurzel (sqrt) aus long long scheint zu funktioneren.

Arduino UNO,MEGA,DUE 
Dunkel die andere Seite ist. - Klappe, Yoda, und iss deinen Toast :-)

michael_x

Die Quadratwurzel (sqrt) aus long long scheint zu funktioneren.
...weil man jede int64_t in eine 32 bit "double" wandeln kann.
Fragt sich nur, ob sich die geringere Genauigkeit bemerkbar macht.


Lt. wikipedia benutzt der Bresenham-Algorithmus nur Integer-Arithmetik, sogar ohne Multiplikation...

rudirabbit

Code: [Select]

Lt. wikipedia benutzt der Bresenham-Algorithmus nur Integer-Arithmetik, sogar ohne Multiplikation...


Das ist schon richtig, nur auch hier wird der Radius des Kreises benötigt.
Hier braucht es ebenso den Pythagoras mit den beiden Werte 159.6*512   4.31*512
Der Code wird mit long beim Quadrieren von (159.6*512) genauso auf die Nase fallen wie meiner.


Mit int64_t funktioniert mein Code mit diesen Werte, nur habe ich auch gleich den Nachteil bei der Methode mit der Kreisformel gesehen.  :(

Der Kreisbogen startet hier zufällig im Bereich der X Achse des Kreises, und hier entsehen erhebliche Rundungsfehler.   
Die Geschwindikeit des Algos wäre nicht das Problem, die Schrittmotoren sind auf jeden Fall langsamer.

Aber die Fehler in den beiden Bereichen sind nicht tragbar.
Also braucht es den Bresenham.  :smiley-mad:
Dieser kann jedoch nur immer in einem Oktant arbeiten, beim Wechsel muß man die "schnelle" Variable mit der "langsamen" tauschen.
Beim Start der Fahrfunktion muss erst der Oktant ermittelt werden, denke das wird ein harter Brocken.
Mal schauen ob ich nicht in den bereits bekannten Projekten (z.b. Marlin)  was klauen kannn.
Arduino UNO,MEGA,DUE 
Dunkel die andere Seite ist. - Klappe, Yoda, und iss deinen Toast :-)

Go Up