Float in Int abbilden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
BlackJack

@Dill: Ketzer! Natürlich weil Python die beste Sprache ist wo gibt. :-D
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

sorry hoffe das zieht jetzt keinen ban nach sich? :oops:
http://www.kinderpornos.info
spongebob.squarepants
User
Beiträge: 54
Registriert: Freitag 22. Mai 2009, 12:59

Wow, ziemlich viele Antworten für nur eine Benachrichtigung. Danke dafür. Sammelantwort folgt:

@sma: Ja, ** würde helfen, danke noch mal für den Hinweis. Bei sqrt fehlen die Fractions. Meine float Repräsentation basiert auf einem long als Vorkomma-Teil und einem sechstelligen long als Nachkommawert.

@numerix: Das Heron Verfahren (ist das die babylonische Wurzel?) konvergiert gut, tendiert aber bei Verwendung des Rational Datentyps (siehe mein letztes Posting), den ich ganz schick finde, selbst bei Verwendung von longs schnell zu Long Overflows, vornehmlich bei dem additiven Part (schon getestet). Aber wenn Du da andere Erfahrungen hast, würde es mich freuen, davon zu hören. Zieht man die Sache mit float durch, ist das Verfahren brauchbar.

@Dill: Mit dem Chip hat das nichts zu tun, es ist ja ein reines in Python 1.5.2 zu lösendes Thema. Firmware für diesen Chip bedarf i.d.R. nicht der float Operation und der Schluss, wenn da keine drüber redet, taugt der nix, ist fraglich. Warum der in Py programmiert wird? Weil der nichts anderes kann (glücklicherweise, wer wünscht sich schon C o.ä., wenn er Py haben kann...). Selbst schreiben ist ja ok. Die Frage war ja: Gibt's da was von Ratiopharm?

@HerrHagen: OK, wie gesagt, extrem problemangepasst. Ich muss positive floats nur mit positiven ints addieren, multiplizieren und dividieren. Wie oben dargestellt, werden Vor und Nachkommastellen in jeweils einem Long abgebildet. Addition und Multiplikation behandeln beide Teile separat, um Überläufe zu vermeiden, und beachtet den Übertrag vom Nachkomma in den Vorkommateil. Die Division ist eine 1:1 Umsetzung der bekannten schriftlichen Division aus der Grundschule. Für SQRT gibt es ja eigentlich auch ein schriftliches Verfahren, ich bin eben nur faul respektive will nicht das Rad nochmal erfinden.

Grüsse und Danke für die Diskussion.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

spongebob.squarepants hat geschrieben:
@Dill: Mit dem Chip hat das nichts zu tun, es ist ja ein reines in Python 1.5.2 zu lösendes Thema. Firmware für diesen Chip bedarf i.d.R. nicht der float Operation und der Schluss, wenn da keine drüber redet, taugt der nix, ist fraglich. Warum der in Py programmiert wird? Weil der nichts anderes kann (glücklicherweise, wer wünscht sich schon C o.ä., wenn er Py haben kann...). Selbst schreiben ist ja ok. Die Frage war ja: Gibt's da was von Ratiopharm?
naja, so ungewöhnlich ist der bedarf an decimal-operationen im embedded bereich ja nun nicht. und ich bleibe dabei, wenn dieses thema in der community noch nicht aufgetaucht ist, muss die sehr klein sein, was mich davon abstand nehmen lassen würde diese technik einzusetzen. ich weiss ja nicht was du damit machst, aber insb. ein professioneller einsatz verbietet sich dann einfach.
ich bin eigentlich ganz glücklich mit C. python ist eine wunderbare sprache, aber auf einem uc will ich die nicht.
http://www.kinderpornos.info
BlackJack

@spongebob.squarepants: Also bei Python's `long`\s dürfte es nicht zu Überläufen kommen, höchstens zu Speicherüberläufen. ;-)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

spongebob.squarepants hat geschrieben:@numerix: Das Heron Verfahren (ist das die babylonische Wurzel?) konvergiert gut, tendiert aber bei Verwendung des Rational Datentyps (siehe mein letztes Posting), den ich ganz schick finde, selbst bei Verwendung von longs schnell zu Long Overflows, vornehmlich bei dem additiven Part (schon getestet). Aber wenn Du da andere Erfahrungen hast, würde es mich freuen, davon zu hören.
Long Overflow :shock:
Das ist dann aber ein Problem dieses Rational-Moduls und kein eigentliches Python-Problem. Ab einer bestimmten Anzahl von Nachkommastellen (ich rede hier von einigen zigtausend) dauert die Berechnung nur einfach zu lange. Begrenzt ist die Genauigkeit nur durch den Hauptspeicher und die Zeit, die du warten willst, bis das Ergebnis kommt ... :)

Und was meinst du mit "additivem Teil"?
Die Idee des Heron-Verfahrens ist die: Man fasst den Radikand als Maßzahl der Fläche eines Quadrats auf und versucht, die Seitenlängen dieses Quadrats zu berechnen - das wäre dann das gewünschte Ergebnis.
Dazu setzt man ein Rechteck mit dem gleichen Flächeninhalt an und approximiert in jedem Schritt die Seiten ein Stück mehr in Richtung Quadrat, indem man in jedem Schritt den Mittelwert der beiden Seiten nimmt (ergibt eine der beiden neuen Seiten) und den Flächeninhalt durch diesen Mittelwert dividiert (ergibt die andere Seite).

Nachtrag: Ein Blick auf bzw. in das Rational-Modul klärt die Sache: Um die float-Repräsentation eines Bruchs a/b darzustellen, wird float(a)/float(b) berechnet. Daraus erklärt sich dann auch der Overflow, denn man kann eben nicht beliebig große ints/longs in floats umwandeln.
spongebob.squarepants
User
Beiträge: 54
Registriert: Freitag 22. Mai 2009, 12:59

@Dill: Ich habe "die Community" dort noch gar nicht gesucht, weil ich hier ein Python Problem sehe. Aber das hatte ich wohl auch schon erwähnt. Ansonsten entscheidet für mich immer, ob der Funktionsumfang des Chips den Anforderungen genügt. Die Sprache ist dann eher zweitrangig. Dieser Chip unterstützt GSM, GPS, WiFi Positionierungen. I.d.R. braucht kein Mensch dafür float oder decimal Support. Lediglich eine spezielle Vorfilterung erfordert diese Rechnereien.

Long Overflow: Ich denke, diese Fehlermeldung ist ziemlich eindeutig:
OverflowError: long int too long to convert. Und sicher - es ist ein Problem des Rational-Moduls, wie man sehen kann, da es nicht mehr als long precision macht in der derzeitigen Realisierung.

Additiver Teil: Ich meinte das hier: http://de.wikipedia.org/wiki/Heron-Verfahren. Die Addition der beiden Rationals erzeugt einen zu grossen Hauptnenner für long .

Die float Repräsentation verwende ich aus naheliegenden Gründen nicht. Ich nutze "print" zur Ausgabe der Ergebnisse. Dort und eben (s.o.) beim HN gibt's den o.g. Overflow.

Grüsse - und bitte keine Diskussion mehr über den Chip. Da bin ich an den AG gebunden. Wer eine Idee hat, wie man mit longs den Pythagoras zwischen zwei floats mit 2-3 Vorkomma und 6 Nachkommastellen machen kann - Willkommen!
BlackJack

@spongebob.squarepants: Das ist aber kein Overflow in Python's `long`\s, sondern ein Problem mit einer Funktion die gerne ein `int` haben möchte.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

spongebob, das sind keine "chips" sondern komplette module, sag das doch, dann muss ich mich nicht erregen. warum rufst du nicht einfach bei telit an, die haben sicher eine fertige lösung für dein problem.
http://www.kinderpornos.info
spongebob.squarepants
User
Beiträge: 54
Registriert: Freitag 22. Mai 2009, 12:59

OK. Welche könnte das sein? Ich habe den Konstruktor von Rational so geändert, dass
self.n = long(a / g)
self.d = long(b / g)

weil mit int ging vorher nicht allzuviel bei der von mir gebrauchten Präzision. Kann ja dann nur ein Print sein, denn die exception zeigt auf diese Stelle
def __str__ ( self ):
'''Display self as a string.
'''
return "%ld/%ld" % ( self.n, self.d )

Hier ein Beispiel:

from rational import *
print Rational(50123456, 1000000) * Rational(151123, 1000000)

Traceback (innermost last):
File "G:\test\t.py", line 2, in ?
print Rational(50123456, 1000000) * Rational(151123, 1000000)
File "G:\test\rational.py", line 84, in __str__
return "%ld/%ld" % ( self.n, self.d )
OverflowError: long int too long to convert

Grüsse
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

spongebob.squarepants hat geschrieben:Wer eine Idee hat, wie man mit longs den Pythagoras zwischen zwei floats mit 2-3 Vorkomma und 6 Nachkommastellen machen kann - Willkommen!
Das ist doch keine große Sache.
Ich mache mal einen Anfang. Was noch fehlt, steht im Quelltext.

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-

def bruch(x):
    """x ist eine Zeichenkette in float-Darstellung.
    Liefert einen gekürzten Bruch z/n als Tupel (z,n)."""
    ganz, nkst = x.rstrip("0").split(".")
    nenner = 10**len(nkst)
    zaehler = int(ganz) * nenner + int(nkst)
    # hier evtl. kürzen
    return zaehler, nenner

def hypotenuse(x, y):
    """x, y sind Zeichenketten mit einer float-Darstellung.
    Liefert das Quadrat der Hypotenuse für die Katheten x und y
    als Bruch (z,n)."""
    (az, an), (bz, bn) = bruch(x), bruch(y)
    cz, cn = az*az*bn*bn+an*an*bz*bz, an*an*bn*bn
    # hier sollte man kürzen: Euklid
    # dann die Quadratwurzel berechnen: Heron
    # und danach ohne Verwendung von float() in eine float-Repräsentation umwandeln
    return cz, cn

a = "6.5004"
b = "2.561"
z, n = hypotenuse(a, b)

# Zur Kontrolle
print float(z)/float(n)
print float(a)**2 + float(b)**2
Schicker wird es natürlich, wenn du einen Klassenentwurf machst und Brüche nicht als Tupel darstellst. Nach meiner Erfahrung leidet darunter allerdings die Performance (falls es darauf ankommt).
spongebob.squarepants
User
Beiträge: 54
Registriert: Freitag 22. Mai 2009, 12:59

@Dill: Nun wollen wir mal nicht kleinlicher sein, als der Papst. Ich hatte die angemailt - keine Antwort.

Ich versuche, ohne dass ich derzeit ein derartiges Modul habe, die "Firmware" vorab auf meinem Nokia (PyS60) zu bauen. Also - wer das nicht schick und interessant findet, hat noch nie für einen 8051 Clone Firmware gebastelt...
spongebob.squarepants
User
Beiträge: 54
Registriert: Freitag 22. Mai 2009, 12:59

@Numerix: Yammi. Das ist doch mal ein Anfang. Probier's gleich mal aus...
Grüsse
spongebob.squarepants
User
Beiträge: 54
Registriert: Freitag 22. Mai 2009, 12:59

Huch? Wass'n hier los?

Traceback (innermost last):
File "G:\test\t1.py", line 25, in ?
z, n = hypotenuse(a, b)
File "G:\test\t1.py", line 16, in hypotenuse
(az, an), (bz, bn) = bruch(x), bruch(y)
File "G:\test\t1.py", line 6, in bruch
ganz, nkst = x.rstrip("0").split(".")
TypeError: strip requires exactly 0 arguments; 1 given
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

spongebob.squarepants hat geschrieben:Huch? Wass'n hier los?

Traceback (innermost last):
File "G:\test\t1.py", line 25, in ?
z, n = hypotenuse(a, b)
File "G:\test\t1.py", line 16, in hypotenuse
(az, an), (bz, bn) = bruch(x), bruch(y)
File "G:\test\t1.py", line 6, in bruch
ganz, nkst = x.rstrip("0").split(".")
TypeError: strip requires exactly 0 arguments; 1 given
Ah, strip() mit Parameter scheint es in Python 1.5 noch nicht gegeben zu haben. Ist kein Problem, kann man auch weglassen. Also einfach:

Code: Alles auswählen

ganz, nkst = x.split(".")
Edit: s.strip(arg) gibt es seit Python 2.2.2
spongebob.squarepants
User
Beiträge: 54
Registriert: Freitag 22. Mai 2009, 12:59

Ich habe hier 2.5.4 lokal zum Testen, kann es sein, dass es das da auch nicht gab?

Grüsse
spongebob.squarepants
User
Beiträge: 54
Registriert: Freitag 22. Mai 2009, 12:59

Nu krachts woanders:
Traceback (innermost last):
File "G:\test\t1.py", line 25, in ?
z, n = hypotenuse(a, b)
File "G:\test\t1.py", line 17, in hypotenuse
cz, cn = az*az*bn*bn+an*an*bz*bz, an*an*bn*bn
OverflowError: integer multiplication
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

spongebob.squarepants hat geschrieben:Nu krachts woanders:
Traceback (innermost last):
File "G:\test\t1.py", line 25, in ?
z, n = hypotenuse(a, b)
File "G:\test\t1.py", line 17, in hypotenuse
cz, cn = az*az*bn*bn+an*an*bz*bz, an*an*bn*bn
OverflowError: integer multiplication
:shock: Dein Python ist nicht in der Lage, mit (beliebig) großen Ganzzahlen zu rechnen. Dürfte es eigentlich gar nicht geben.
spongebob.squarepants
User
Beiträge: 54
Registriert: Freitag 22. Mai 2009, 12:59

Ich korrigiere: Ein print sys.version brachte etwas ans Licht, was ich schon vermutet hatte: Ich habe zwar 2.5.4 auf dem PC und die erscheint auch, wenn ich auf der Console "python" eingebe, aber die _nachträgliche_ Installation des Telit EasyScript Paketes hat die Verknüpfung von "*.py" Dateien auf die von denen installierte 1.5.2 umgebogen...

Argghghg
spongebob.squarepants
User
Beiträge: 54
Registriert: Freitag 22. Mai 2009, 12:59

.... deswegen wohl auch die Missverständnisse mit dem Overflow...

Nun, Py 1.5.2 zeigt es: Es _gab_ mal eine Python-Variante, die das nicht konnte :)

Und wieder die Frage: Gibt's da was von Ratiopharm? Entschuldigung, wenn ich so nerve und vielen Dank für Deine/Eure Patience.

Grüsse
Antworten