Unerwartetes Ergebnis bei Modulo
Unerwartetes Ergebnis bei Modulo
am 02.10.2007 14:27:30 von Hendrik Schnepel
Hallo Newsgroup,
ich habe gerade in einem Forum eine Frage gelesen, die ich mir selbst
nicht ganz beantworten kann.
Warum werden hier zwei verschiedene Ergebnisse ausgegeben:
hsch@tango perl -le 'print 7382 % 100'
82 (wie erwartet)
hsch@tango perl -le 'print +(73.82 * 100) % 100'
81 (eher ueberraschend?)
Das ganze passiert nur bei bestimmten Kombinationen von Vor- und
Nachkommaziffern. Eine int(...) Anweisung hilft auch nicht weiter.
Was wieder erwartungsgemaess arbeitet, ist:
hsch@tango perl -le 'print +((73.82 * 100)."") % 100'
Aber das ist doch wirklich unschoen...
Kann mir jemand sagen, wie dieser Effekt zustande kommt (ich vermute mal
irgendetwas, das durch interne (floating point?) Darstellung verursacht
wird), und wie man obige Rechnung evtl. besser programmieren koennte?
Gruss,
Hendrik
Re: Unerwartetes Ergebnis bei Modulo
am 02.10.2007 14:48:50 von Roman Racine
Hendrik Schnepel wrote:
> Kann mir jemand sagen, wie dieser Effekt zustande kommt (ich vermute mal
> irgendetwas, das durch interne (floating point?) Darstellung verursacht
> wird), und wie man obige Rechnung evtl. besser programmieren koennte?
Das kommt durch Floating-Point Arithmetik zustande, d.h. in der
Floatingpoint-Arithmetik ist die Zahl eben nicht ganz 7382, sondern ein
klein wenig weniger.
perl -le 'print int(73.82 * 100)'
gibt nämlich 7381.
Mit solchen unerwarteten Ergebnissen musst du grundsätzlich mit jeder
gängigen Programmiersprache rechnen, wenn du Ganzzahlarithmetik und
Gleitkommaarithmetik mischst. Solange du endliche Präzision verwendest,
wird man immer ein Beispiel wie das obige konstruieren können, wo die
interne Darstellung gerade ein kleines bisschen weniger als die ganze Zahl
ist.
Mit Math::BigFloat kriegst du das gewünschte Ergebnis. Allerdings ändert es
nichts daran, dass eine Operation wie die von dir vorgeschlagene ziemlich
"unschön" ist, weil sehr unerwartete Ergebnisse rauskommen können.
Möglicherweise gibt es andere Wege, wie du zum gewünschten Ziel kommen
könntest. Das könnte man beurteilen, wenn du uns erklären würdest, was du
eigentlich genau erreichen willst.
Gruss
Roman°
--
IRC-Freenode: #usenet-friends
http://www.usenet-friends.ch.vu/
Re: Unerwartetes Ergebnis bei Modulo
am 02.10.2007 20:07:47 von Florian Weimer
* Hendrik Schnepel:
> Warum werden hier zwei verschiedene Ergebnisse ausgegeben:
>
> hsch@tango perl -le 'print 7382 % 100'
> 82 (wie erwartet)
>
> hsch@tango perl -le 'print +(73.82 * 100) % 100'
> 81 (eher ueberraschend?)
73.82 sind 3691 Fünftel, und Fünftel lassen sich in einer
Binärdarstellung nicht exakt wiedergeben, im Gegensatz zur Basis 10.
Re: Unerwartetes Ergebnis bei Modulo
am 03.10.2007 12:18:44 von Hendrik Schnepel
This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.
---559023410-851401618-1191406724=:15055
Content-Type: TEXT/PLAIN; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8BIT
Hallo Roman,
danke fuer die Details, alles klar. Ich hatte soetwas erwartet, aber mich
trotzdem gewundert, ... naja ;)
> Möglicherweise gibt es andere Wege, wie du zum gewünschten Ziel kommen
> könntest. Das könnte man beurteilen, wenn du uns erklären würdest, was du
> eigentlich genau erreichen willst.
Es ging darum, den Cent-Anteil eines Geldbetrags zu ermitteln. Das
letztendlich funktionierend zu implementieren ist aber kein Problem :)
Gruss,
Hendrik
---559023410-851401618-1191406724=:15055--
Re: Unerwartetes Ergebnis bei Modulo
am 08.10.2007 12:31:35 von Ingo Menger
On 3 Okt., 12:18, Hendrik Schnepel
wrote:
> Hallo Roman,
>
> danke fuer die Details, alles klar. Ich hatte soetwas erwartet, aber mich
> trotzdem gewundert, ... naja ;)
>
> > Möglicherweise gibt es andere Wege, wie du zum gewünschten Ziel kom=
men
> > könntest. Das könnte man beurteilen, wenn du uns erklären würde=
st, was du
> > eigentlich genau erreichen willst.
>
> Es ging darum, den Cent-Anteil eines Geldbetrags zu ermitteln. Das
> letztendlich funktionierend zu implementieren ist aber kein Problem :)
Aber mit Geldbeträgen in binärer Gleitkommarithmetik zu rechnen ist
ein Problem. Wie Florian schon richtig begründet hat, geht das bei den
meisten Centbeträgen in die Hose, denn 1/100 =3D 1/(5*5*2*2) und 5 ist
teilerfremd zu 2. Das heißt, Du kannst überhaupt nur 4 Centbeträge
genau darstellen: 0, 25, 50 und 75