Seite 1 von 1

Dezimaldarstellung kleiner Zahlen

Verfasst: Samstag 12. Oktober 2013, 14:39
von bs20253
Hallo und guten Tag!

Ich möchte gerne sehr kleine Zahlen in Dezimalschreibweise darstellen.(Wie kommt man jetzt darauf: Ganz einfach, meine Tochter wollte wissen, wieviel ist 0.001 * 0.01 * 0.0048 und fand dann die Antwort 4.8e-08 "doof, weil man die Nullen nicht sieht". OK....dann wollen wir mal ...öööö, hm ...da sah Papa dann nicht gut aus). %f und .format versagt, da zumindest bei mir (py 3x) nach 6 Nachkommastellen Schluß ist. Nun könnte man einen String basteln, käme man an den Exponenten.

Frage 1: Gibt es eine Funktion, die z.B. Mantisse und Exponent einer float Zahl als Tupel liefert?
Frage 2: oder gibt es gar eine andere einfache Lösung.

Danke
Gruß
Bernhard

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Samstag 12. Oktober 2013, 15:02
von jerch
Willkommen im Forum!

Zu Frage 1:
Im Modul math gibt es die Funktion `frexp`, die Dir die Mantisse und den Exponenten ausspuckt. Ist aber, wer hätte es gedacht, im Format m * 2 ^ e, also für die Betrachtung im 10er System nicht unbedingt einfacher ;)

Zu Frage 2:
Sowas vielleicht?

Code: Alles auswählen

>>> a = 0.00000001
>>> a
1e-08
>>> '{:.10f}'.format(a)
'0.0000000100'
>>> 

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Samstag 12. Oktober 2013, 15:06
von Sirius3
Hallo Bernhard,
man kann bei der Formatangabe die Anzahl der Nachkommastellen mit angeben:

Code: Alles auswählen

>>> zahl = 4.8e-8
>>> '%.9f'%zahl
'0.000000048'
>>> exponent = math.floor(math.log10(zahl))
>>> mantisse = zahl/10**exponent
>>> mantisse,exponent
(4.8, -8.0)

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Samstag 12. Oktober 2013, 17:37
von bs20253
Hallo!

Zuerst vielen Dank für die Antworten!


Da das Folgende nicht im Sinne des Gewünschten ist:

Code: Alles auswählen

>>> zahl = 0.1
>>> print ('%.9f'%zahl)
0.100000000
habe ich ein wenig gefummelt, da es mir nicht gelungen ist, Formatierungen ineinander zu verschachteln.
Sofern das geht, ist das Folgende eine nette kleine Übung ;-)

Code: Alles auswählen

def min_float_to_str(fnum):
    #wir bestimmen den Exponent = Zahl < 0?
    exponent = math.floor(math.log10(fnum))
    if exponent < 0:
	#wir ziehen ein Stelle ab wegen der mantisse
	stellen = abs(exponent)-1
	#wir bestimmen die Mantisse = "Zahl"
	mantisse = fnum/10**exponent
	#wir verwandeln die Mantisse in eine Zahl ohne Komma
	#wir erhalten die Mantisse für evtl späteren Gebrauch
	num = mantisse
	while num %1 != 0:
            num = num * 10
	#und erzwingen den integer
	num = int(num)
	#und basteln den string
	return "0." + (int(stellen) *'0') + str(num)
    else:
	return str(fnum)
Test

Code: Alles auswählen

>>> zahl = 123456
>>> min_float_to_str(zahl)
'123456'
>>> zahl = 0.1
>>> min_float_to_str(zahl)
'0.1'
>>> zahl = 3.41275e-13
>>> min_float_to_str(zahl)
'0.000000000000341275'
Danke nochmals
Gruß
Bernhard

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Samstag 12. Oktober 2013, 17:53
von BlackJack
@bs20253: Einfach alle 0en rechts zu beseitigen wäre wahrscheinlich zu einfach:

Code: Alles auswählen

In [23]: '{:.9f}'.format(0.1).rstrip('0')
Out[23]: '0.1'

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Samstag 12. Oktober 2013, 19:46
von bs20253
Gute Idee - auf jeden Fall.
Die Voraussetzung ist dann, dass keine Zahl eintritt als kleiner %nf.
Kinder und der DAU können das, auch bei 99 :roll:

Trotzdem gute Idee, auf die ich nicht gekommen bin.

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Samstag 12. Oktober 2013, 20:14
von EyDu
bs20253 hat geschrieben:Die Voraussetzung ist dann, dass keine Zahl eintritt als kleiner %nf.
Das ist eigentlich gar kein Problem, denn ab spätestens 17 Stellen hast du bei floats so oder so verloren. Im Prinzip schon deutlich vorher, da ja noch nicht einmal 0.1 eine endliche Darstellung im Binärsystem hat, was bei Multiplikationen natürlich zu interessanten Ergebnissen führen wird. Hier bietet sich dann das decimal-Modul an.

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Sonntag 13. Oktober 2013, 07:56
von bs20253
Danke auch für diesen Hinweis.
Damit wäre dann die Lösung von BlackJack mit Deinem n die mit dem geringsten Schreibaufwand

Code: Alles auswählen

In [23]: '{:.17f}'.format(0.1).rstrip('0')
Out[23]: '0.1'
Was auch noch zu der Bemerkung führt: wer min_float_to_str einsetzen will, muss auch import math machen - dann funzt ohnehin aber auch .nf mit n<18 (und die procedure knallt natürlich bei der float-Grenze an die Wand). Also überflüssig. Vermutlich ist format.rstrip auch noch der schnellste Rechenweg aufgrund des intern optimierten Speichermanagments. :-(. Aber manchmal ist es eben schneller, eigenen Unsinn zu verzapfen, als das Hirn zu quälen...

Auf jeden Fall wieder was gelernt. Danke für alle Hinweise.
Gruß
Bernhard

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Sonntag 13. Oktober 2013, 10:32
von Sirius3
@EyDu: floats haben maximal 17 signifikante Stellen. Es kann also sehr wohl sein, dass noch 99 nullen hinter dem Komma stehen, bevor die 17 Stellen anfangen.

Code: Alles auswählen

>>> '%.17f'%0.1
'0.10000000000000001'
>>> '%.17f'%0.15
'0.14999999999999999'
>>> '%.99f'%0.1
'0.100000000000000005551115123125782702118158340454101562500000000000000000000000000000000000000000000'
>>> '%.99f'%0.1e-30
'0.000000000000000000000000000000100000000000000008333642060758598535093133602686865450236450978354886'
Man muss also ziemlich genau wissen, wieviele reale Stellen die Zahl haben soll.
Um mir die Arbeit deutlich zu vereinfachen, erlaube ich nur 16 signifikante Stellen, weil die letzte ja nur so halb signifikant ist.

Code: Alles auswählen

import math
def min_float_to_str(zahl):
    exponent = math.floor(math.log10(zahl))
    stellen = max(1,int(-exponent+15))
    return ('%%.%df'%stellen%zahl).rstrip('0').rstrip('.')
 
print min_float_to_str(1.499999999999999999e+5)
print min_float_to_str(1.5e-30)

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Sonntag 13. Oktober 2013, 12:25
von bs20253
Cool! Formatierte Formatierung! Das gefällt

Code: Alles auswählen

'%%.%df'%stellen%zahl
Auf jeden Fall auch eine interessante Lösung. Langsam wird der thread sportlich 8)

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Montag 14. Oktober 2013, 10:55
von EyDu
Sirius3 hat geschrieben:@EyDu: floats haben maximal 17 signifikante Stellen. Es kann also sehr wohl sein, dass noch 99 nullen hinter dem Komma stehen, bevor die 17 Stellen anfangen.
Das hast du natürlich Recht. Ich schiebe meinen Ausfall einfach mal auf die Uhrzeit und meine Überarbeitung :roll:

Re: Dezimaldarstellung kleiner Zahlen

Verfasst: Montag 14. Oktober 2013, 12:09
von diesch

Code: Alles auswählen

'%%.%df'%stellen%zahl
lässt sich etwas eleganter als

Code: Alles auswählen

'%.*f' % (stellen, zahl)
schreiben