floats to int

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.
typ

floats to int

Beitragvon typ » Sonntag 16. Oktober 2005, 23:46

hallo, ich bins nochmal. Weis jemand wie ich, wenn ich zwei floats habe, die länge von den nachkommastellen bestimmen kann? ich frage, weil ich zwei float zahlen habe und beide mit einer zahl multiplizieren will, sodass am ende sie beide keine nachkommastellen mehr haben. ich multipliziere sie gerade mit 10^50. Vielleicht kann man auch mit mod was machen?
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Beitragvon rayo » Montag 17. Oktober 2005, 01:10

Hi

Ich versteh dich leider nicht ganz. Meinst du sowas:

Code: Alles auswählen

resultat = int(float1*float2)


Gruss
typ

Beitragvon typ » Montag 17. Oktober 2005, 06:41

Nein, ich habe eine float und möchte wissen, mit welcher Zahl ich es multiplizieren muss damit es eine Ganzzahlige Zahl wird
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Montag 17. Oktober 2005, 07:10

Hallo "typ",

das geht SO nicht. Fließkommazahlen bleiben Fließkommazahlen im Computer - egal mit was Du multiplizierst oder dividierst. Was Du machen kannst ist:
- runden:

Code: Alles auswählen

round(0.54,1) #ergibt 0.5
round(0.54) #ergibt 1

- oder konvertieren:

Code: Alles auswählen

int(1.1) #ergibt 1

Anders wirst Du die Nachkommastellen nicht los. Wenn Du eine Fließkommazahl mit einer wahnsinnig großen anderen Zahl multiplizierst kommt wieder eine Fließkommazahl heraus. (Bei einem kleinem Integer kommt ein sog. Long Integer heraus, aber das mußt Du noch nicht einmal bemerken.
Das Problem ist nicht so sehr mathematisch, es hat damit zu tun wie Rechner (nicht Python!) Daten behandeln.
Vielleicht ist dies noch für Dich von Interesse?

Gruß,
Christian
typ

Beitragvon typ » Montag 17. Oktober 2005, 14:42

klar ist es dann noch vom typ float aber dann kann ich es in int konvertieren ohne dass ich nachkommastellen verliere. Ok, ein Beispiel:

Ich habe die Zahl 0.0003. Diese will ich mit irgendwas multiplizieren, damit eine Ganze Zahl rauskommt. Ich nehme hier die 10000: 10000*0.00003 = 3
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Montag 17. Oktober 2005, 15:44

Hoi,

Du kannst das nicht herausbekommen - jedenfalls nicht in den meisten Fällen. Die Frage wäre doch: Welches ist die letzte Nachkommastelle meiner Zahl (die Position)?
Also, nehme einmal an Deine Zahl lautet 0.5. Das ist eindeutig. Du kannst dann mit 10 multiplizieren. Aber was ist, wenn Deine Zahl 0.4 lautet? Dann nämlich ist diese Zahl nicht eindeutig zu greifen und Python wird (das kann bei Deinem Rechner anders sein!) sie als 0.40000000000000002 darstellen. Also willst Du mit 10000000000000000 multiplizieren? Gut, aber was bringt Dir das?
Vielleicht möchtest Du mal eher einen Blick auf das deccimal Modul werfen.

Gruß,
Christian
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Montag 17. Oktober 2005, 16:07

Da hätten wir schon eine halbwegs annehmbare Lösung:

Code: Alles auswählen

#!/usr/bin/env python
# -*- encoding: latin-1 -*-
import decimal

value = decimal.Decimal('0.000300')

def get_multi(value):
    multi = 10

    while True:
        temp = multi * value
        if temp >= 3:
            return multi
           
        multi = multi * 10

print get_multi(value)

Die Ungenauigkeit von floats scheint hier ganz übel durch :evil:
My god, it's full of CARs! | Leonidasvoice vs Modvoice
typ

Beitragvon typ » Montag 17. Oktober 2005, 17:59

Ja, aber wenn du nicht weist, das value ist, könnte ja auch 0,0003200 sein. Dann ist bei 3,2 größer als 3 aber immer noch keine ganze Zahl
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Montag 17. Oktober 2005, 20:03

Ja, dann modifiziere halt Leonidas Skript: Überprüfe nicht, ob Du über einen best. Schwellenwert kommst, sondern Du kannst abfragen, ob es noch Nachkommastellen hat (nach dem Komma != 0 ?).

Leonidas hat geschrieben:Die Ungenauigkeit von floats scheint hier ganz übel durch

Na ja, Fließkommazahlen sind nicht "genau", aber man sollte nicht der Illusion unterliegen, daß andere Lösungen "genauer" sind. IMHO braucht man eigentlich nur im Falle seltener wissenschaftlicher Anwendungen größere Präzission (oder für die Finanzmathematik, aber da gibt es ja für Python decimal) - und da muß man sich zur Not halt den entsprechenden Datentyp selber schaffen ;-). Aber sonst: Sind irgenwelche Instrumte wirklich so präzise, daß double-precission nicht ausreicht?

Mir scheint "typ", Du schießt mit Kanonen auf Spatzen - deshalb habe ich nach dem Wozu gefragt.

Gruß
Christian
Leto
User
Beiträge: 6
Registriert: Donnerstag 27. Juli 2006, 15:23

Beitragvon Leto » Donnerstag 27. Juli 2006, 15:33

Klar geht das Ganze. Und zwar auch noch sehr einfach:
[code=]
def getMult(zahl):

mult=1
while zahl%1 != 0:
mult=mult*10
zahl=zahl*10
return mult
[/code]

zur Erläuterung:

Dividiert man eine Zahl durch 1 und erhält Null als Rest, so hat diese Zahl zwangsläufig keine Nachkommastellen.
Die Funktion prüft genau dies und multipliziert solange mit 10, bis diese Bedingung erfüllt ist.
Den notwendigen Multiplikator gibt sie gleich mit aus.

(eine nützliche Funktion, um die nachkommastellen zu zählen bzw. mit Integer anstelle von float-Werten zu rechnen [Ganauigkeit])
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Beitragvon CrackPod » Donnerstag 27. Juli 2006, 16:06

Wahrscheinlich ne dumme Idee, aber:
Man könnte den float in ein string umwandeln. Danach splitten wir den string beim . und zählen danach die nachkommastellen per len.
Dann multipliziert man das ganze und fertig :wink:

Code: Alles auswählen

>>> a = 5.0234
>>> as = str(a)
>>> b = as.split('.')
>>> b
['5', '0234']
>>> len(b[1])
4
>>> mult = '1' + '0' * len(b[1])
>>> mult
'10000'
>>> print a * int(mult)
50234.0
>>> c = a * int(mult)
>>> c
50234.0
>>> int(c)
50234
Geht doch ;)
Und als Funktion:

Code: Alles auswählen

def floatToInt(flt):
   fltStr = str(flt)
   decimals = fltStr.split('.')
   decimals = len(decimals[1])
   mult = int('1' + '0' * decimals)
   return int(flt * mult)
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Donnerstag 27. Juli 2006, 19:32

CrackPod hat geschrieben:Wahrscheinlich ne dumme Idee, aber:
Man könnte den float in ein string umwandeln. Danach splitten wir den string beim . und zählen danach die nachkommastellen per len.

Das ist gar nicht so dumm.
CrackPod hat geschrieben:Und als Funktion:

Code: Alles auswählen

def floatToInt(flt):
   fltStr = str(flt)
   decimals = fltStr.split('.')
   decimals = len(decimals[1])
   mult = int('1' + '0' * decimals)
   return int(flt * mult)

Hier würde ich etwas kürzen:

Code: Alles auswählen

def f2i(f):
    return int(f * 10**len(str(flt).split('.')[1]))

Man muss hier halt darauf achten, dass man max. 12 Nachkommastellen bekommt (in float.__str__() eingebaut), dafür aber die formatbedingten Ungenauigkeiten in den meisten Fällen ausgemerzt hat.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Donnerstag 27. Juli 2006, 20:52

birkenfeld hat geschrieben:Hier würde ich etwas kürzen:

Code: Alles auswählen

def f2i(f):
    return int(f * 10**len(str(flt).split('.')[1]))

Hi birkenfeld!

Ich würde mir an deiner Stelle mal Perl ansehen und Python sausen lassen. :?

mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Donnerstag 27. Juli 2006, 20:55

Ach was. Es ist (für mich zumindest) auch nicht schwieriger, so einen Einzeiler zu erfassen, als fünf Zeilen mit lauter temporären Namen. ;-)

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot], Majestic-12 [Bot]