Seite 1 von 2

kaufmännisch runden und Problem bei Werteübergabe

Verfasst: Donnerstag 17. Oktober 2002, 09:54
von reggid

Code: Alles auswählen

def Runden(zahl): # meine Funktion zum Runden
    if (zahl<int(zahl)+0.5):
        zahl=int(zahl) #Abrunden !
    else:
        zahl=int(ceil(zahl)) #Abrunden !
    return zahl
Diese Funktion soll Zahlen runden, wenn die Zahl >=0.5 liegt aufrunden und drunter liegt abrunden !
Wenn ich aber nun eine Zahl übergebe, sagen wir 1.745 , also
Runden(1.745), dann kommt dort automatisch nur 1 an und dann kann man das runden vergessen !
So wie kann ich mich diesem Problem entledigen ?

Re: kaufmännisch runden und Problem bei Werteübergabe

Verfasst: Donnerstag 17. Oktober 2002, 11:29
von Voges
Hallo!
reggid hat geschrieben: Wenn ich aber nun eine Zahl übergebe, sagen wir 1.745 , also
Runden(1.745), dann kommt dort automatisch nur 1 an und dann kann man das runden vergessen !
Hm, dann musst Du schon beim Aufruf der Funktion was falsch machen. Bei mir funktioniert es:

print Runden(1.345) -> Ausgabe: 1
print Runden(1.745) -> Ausgabe: 2


Es geht aber auch kürzer:

Code: Alles auswählen

def Runden(zahl):
    return int(zahl + 0.5)
Allerdings, beide Funktionen runden bei negativen Zahlen falsch. Besser wäre da wohl folgende Lösung:

Code: Alles auswählen

def Runden(zahl):
    if zahl >= 0:
        return int(zahl + 0.5)
    else:
        return int(zahl - 0.5)
Jan

Danke

Verfasst: Donnerstag 17. Oktober 2002, 12:52
von reggid
Jo du hast recht deine Funktion ist viel einfacher und meine Rechnnungen hießen alle a/7 anstatt a/7.00, deswegen vielen einfach die Nachkommastellen weg *g*

Verfasst: Donnerstag 17. Oktober 2002, 13:58
von Dookie
Hallo,

mit der Funktion floor aus dem math-Modul spart mann sich die Abfrage vom Vorzeichen.

Code: Alles auswählen

from math import *

Runden = lambda x: floor(x+0.5)

a = 1.5
b = 1.75

print Runden(a)
1.0
print Runden(b)
2.0
print Runden(-a)
-1.0
print Runden(-b)
-2.0

Gruß

Dookie

Verfasst: Donnerstag 17. Oktober 2002, 14:32
von Voges
Hallo!
Dookie hat geschrieben:a = 1.5
print Runden(-a)
-1.0
Ich bin jetzt etwas verunsichert. Ich dachte, beim Runden wird nur der Betrag beachtet, also unabhängig vom Vorzeichen. Also, |-1.5| ist 1.5 und ergibt nach der Rundungsregel, dass ab .5 aufgerundet wird, 2 für den Betrag und somit schließlich -2. (das 1.5 -> 1.0 wird ein Typo von Dir sein.)

Jan

Verfasst: Donnerstag 17. Oktober 2002, 14:44
von Dookie
Hi Voges,

jo stimmt, mein Fehler, ausserdem sollte es heissen a=1.25 ;)
Aber mit einer kleinen Änderung lässt sich das Fehlverhalten leicht beheben.

Code: Alles auswählen

from math import *

Runden = lambda x: floor(x+0.499999)

a = 1.25
b = 1.75
c = 1.5

print Runden(a)
1.0
print Runden(b)
2.0
print Runden(c)
2.0

print Runden(-a)
-1.0
print Runden(-b)
-2.0
print Runden(-c)
-2.0
kommt wohl daher, daß die Computer intern binär rechnen.


Gruß

Dookie

Verfasst: Donnerstag 17. Oktober 2002, 14:47
von Voges
Hallo!
Dookie hat geschrieben:Runden = lambda x: floor(x+0.499999)
jetzt klappt es für 1.5 nicht mehr.
Ein Versuch hast Du noch. :-)
Jan

Verfasst: Donnerstag 17. Oktober 2002, 14:56
von Dookie
Gerade gemerkt :D

Code: Alles auswählen

Runden = lambda x: floor(x+0.5+((x/(abs(x+0.000001))*0.000001)))
mit Trick 17 1/2 funktionierts :P


Gruß

Dookie

Verfasst: Donnerstag 17. Oktober 2002, 15:19
von Voges
Hallo!
Dookie hat geschrieben: Runden = lambda x: floor(x+0.5+((x/(abs(x+0.000001))*0.000001)))

mit Trick 17 1/2 funktionierts :P
Trick 17 wollte ich gerade kommentieren :-). Da warst Du schneller. Jetzt hast Du eigenlich nur noch das (vielleicht vernachlässigbare) Problem eines ZeroDivisionErrors, wenn x = -0.000001.
Jan

Verfasst: Donnerstag 17. Oktober 2002, 15:28
von Dookie
Hi Voges,

nun die ultimative Lösung:

Code: Alles auswählen

Runden = lambda x: floor(x+0.5+(0.000001* ((not x) or (x/abs(x)))))
wer da noch durchblickt ist selber schuld :lol:


Gruß

Dookie

Verfasst: Donnerstag 17. Oktober 2002, 15:58
von Voges
Hallo!
Dookie hat geschrieben:Runden = lambda x: floor(x+0.5+(0.000001* ((not x) or (x/abs(x)))))
Jaaaa, 'not x or' ist die Lösung! Eigentlich eine Technik, die man bei Perl früh lernt, die mir bei Python noch nicht so häufig untergekommen ist. Das x/abs(x) hatte ich auch schon, aber wegen x == 0 sofort verworfen. Aber so geht es.
Hier noch zwei vielleicht lesbarere Varianten, die hoffentlich funktionieren (besonders gut gefällt mir das "not x or x"):

Runden = lambda x: int(x+0.5 * ((not x) or (x/abs(x))))
Runden = lambda x: int(x+0.5 * (x/abs(not x or x)))

Jan

Nachtrag:
Runden = lambda x: int(x+ 0.5 * ((x > 0) or -1))
Und nu' kommst Du ;-)
Jan

Verfasst: Donnerstag 17. Oktober 2002, 16:21
von Dookie
Python is schön :D


Dookie

Verfasst: Donnerstag 17. Oktober 2002, 18:49
von Voges
hallo!
Dookie hat geschrieben:Python is schön :DDookie
Ich glaube, Du kann die beiden Snippet-Beiträge wieder löschen.

round(x[, n]) existiert als Build-In Funktion :-\
Jan

Verfasst: Donnerstag 17. Oktober 2002, 18:59
von Dookie
Hi Jan,

:lol:

hat aber trotzdem spaß gemacht! :)
Und als Beispiele sind sie immer noch brauchbar.

Dookie

Verfasst: Donnerstag 17. Oktober 2002, 21:50
von RicmanX
Voges hat geschrieben:hallo!
Ich glaube, Du kann die beiden Snippet-Beiträge wieder löschen.

round(x[, n]) existiert als Build-In Funktion :-\
Jan

Code: Alles auswählen

>>> round(1.35,1)
1.3999999999999999
Das ist nur eine von vielen "Möglichkeiten" die ich bei der Erstellung meines Downloadscriptes entdeckte ;)

Verfasst: Donnerstag 17. Oktober 2002, 22:08
von hans
Jetz muß ich doch auch mal wieder mitmischen :D

wie weit ist 1,39999999999 von 1,40 entfern? Denke, der Fehler ist vernachlässigbar klein. Und wenns beim Ausdruck stört dann schreib doch

Code: Alles auswählen

print '%8.2f" % 1.4999999999999'
Ich weiß nicht ob es sich lohnt, den Differenzbetrag auf mein Konto zu überweisen:D

Hans

Verfasst: Donnerstag 17. Oktober 2002, 22:21
von Voges
Hallo!
RicmanX hat geschrieben:>>> round(1.35,1)
1.3999999999999999
Dafür reicht schon Folgendes:
>>> 1.0/10
0.10000000000000001
>>>

Aber das liegt nun mal in der Natur der Sache, sprich der internen Darstellung von Fließkommazahlen.

Jan

Verfasst: Donnerstag 17. Oktober 2002, 22:34
von hans
Ich weiß daß das sp ist, auch wenn ich nicht weiß wie man Fließkomma in Biär darstellt. Das tut aber auch nichts zu Sache. Nur diese Pfennigsfuchserei.....

Ich hole mal gerade mein altes Lehrbuch (Küster Thiel Fischbeck, Logarithmische Rechentafeln, 100. Auflage, 1969)
Der Mangel an mathematischer Bildung gibt sich durch nichts so auffallend zu erkennen, wie durch maßlose Schärfe im Zahlenrechnen

C.F. Gauss

Verfasst: Freitag 18. Oktober 2002, 10:01
von RicmanX
Das Problem ist ja das man mit den Zahlen - ich zumindest - weiterrechnen muss, und Genauigkeit ist auch notwendig.
Und wenn ich ne Zahl mit zehn Nachkommastellen hab, ist das genauso schlecht wie wenns 50 auch nur um nicht sehr viel falsch ist... alle andern Sprachen können schließlich rechnen, das und das Python nur auf wenigen Servern installiert ist ist mE das einzige Manko an Python.

Verfasst: Freitag 18. Oktober 2002, 13:52
von Dookie
Hi RicmanX,
RicmanX hat geschrieben:alle andern Sprachen können schließlich rechnen
Welche?
Lass mal

Code: Alles auswählen

((10.0*3.0)/3.0)-((10.0/3.0)*3.0)
berechnen.
Und dann sag mir bei welcher Sprache das richtige Ergebnix nämlich 0.0 rauskommt.


Gruß

Dookie

P.S.: ich habs grad mit Python probiert, und wundersamerweise kommt 0.0 raus :D