Genauigkeit in Perl

Hallo zusammen,

hier mein Code. Am Ende sollte fuer $sum 1.0 rauskommen, tut es aber
nicht. Es kommt mehr raus - abhängig von der Genauigkeit. Jetzt rechnet
Perl aber schon per default mit doppelter Genauigkeit. Wie kann ich das
Problem vermeiden?
Grüsse

Stefan
------------------------------------------------------------ -------
use warnings;
use strict;


my $nr=250000;
my $step=1/$nr;
print "$step \t";
my $sum=0;
for (1..$nr){$sum=$sum+$step};
print "$sum \n";
Stefan Kristukat [ Mi, 01 März 2006 17:15 ] [ ID #1210553 ]

Re: Genauigkeit in Perl

Stefan Kristukat schrieb:

> Hallo zusammen,
>
> hier mein Code. Am Ende sollte fuer $sum 1.0 rauskommen, tut es aber
> nicht. Es kommt mehr raus - abhängig von der Genauigkeit. Jetzt rechnet
> Perl aber schon per default mit doppelter Genauigkeit. Wie kann ich das
> Problem vermeiden?
> Grüsse
>
> Stefan
> ------------------------------------------------------------ -------
> use warnings;
> use strict;
>
>
> my $nr=250000;
> my $step=1/$nr;
> print "$step \t";
> my $sum=0;
> for (1..$nr){$sum=$sum+$step};
> print "$sum \n";

Denk drüber nach und post wieder, wenn du auf der Welt irgendeine
Programmiersprache gefunden hast, die bei dieser Vorgehensweise 1.0 als
Ergebnis liefert.

Gruß
Karlheinz
Karlheinz Weindl [ Mi, 01 März 2006 17:28 ] [ ID #1210554 ]

Re: Genauigkeit in Perl

Karlheinz Weindl wrote:
> Stefan Kristukat schrieb:
>>
>>my $nr=250000;
>>my $step=1/$nr;
>>print "$step \t";
>>my $sum=0;
>>for (1..$nr){$sum=$sum+$step};
>>print "$sum \n";
>
> Denk drüber nach und post wieder, wenn du auf der Welt irgendeine
> Programmiersprache gefunden hast, die bei dieser Vorgehensweise 1.0 als
> Ergebnis liefert.

Dafür kommen alle Programmiersprachen infrage, die 1/250000
exakt als 0.000004 darstellen können. Perl kann das mit
ein bisschen Unterstützung auch:

use Math::BigFloat;

my $nr=250000;
my $step=Math::BigFloat->new(1);
$step->bdiv($nr);
print "$step \t";
my $sum=0;
for (1..$nr){$sum=$sum+$step};
print "$sum \n";

Davon, das die Berechung schnell gehen soll,
war ja nicht die Rede :)

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Frank Seitz [ Mi, 01 März 2006 18:36 ] [ ID #1210555 ]

Re: Genauigkeit in Perl

Karlheinz Weindl schrieb:
> Stefan Kristukat schrieb:
>> my $nr=250000;
>> my $step=1/$nr;
>> print "$step \t";
>> my $sum=0;
>> for (1..$nr){$sum=$sum+$step};
>> print "$sum \n";
>
> Denk drüber nach und post wieder, wenn du auf der Welt irgendeine
> Programmiersprache gefunden hast, die bei dieser Vorgehensweise 1.0 als
> Ergebnis liefert.

Zählt Mathematica als Programmiersprache?
nr = 250000;
step = 1/nr;
Print[step];
sum = 0;
For[i = 1, i <= nr, i++, sum = sum + step];
Print[sum];

liefert
1/250000
1

Geht also! ;-)

Wenn man das so in Perl machen möchte (aus was für einem Grund auch
immer), dann muss eben ein wenig Bruchrechnen und Zähler und Nenner
verarbeiten.

Hier kann man einfach von $i von 1 bis 250000 laufen lassen und jeweils
als Teilsumme $sum=$i/250000 schreiben.

Wolf
Wolf Behrenhoff [ Mi, 01 März 2006 18:42 ] [ ID #1210556 ]

Re: Genauigkeit in Perl

Frank Seitz schrieb:

> Karlheinz Weindl wrote:
>
>>Stefan Kristukat schrieb:
>>
>>>my $nr=250000;
>>>my $step=1/$nr;
>>>print "$step \t";
>>>my $sum=0;
>>>for (1..$nr){$sum=$sum+$step};
>>>print "$sum \n";
>>
>>Denk drüber nach und post wieder, wenn du auf der Welt irgendeine
>>Programmiersprache gefunden hast, die bei dieser Vorgehensweise 1.0 als
>>Ergebnis liefert.
>
>
> Dafür kommen alle Programmiersprachen infrage, die 1/250000
> exakt als 0.000004 darstellen können. Perl kann das mit
> ein bisschen Unterstützung auch:
>
> use Math::BigFloat;
>
> my $nr=250000;
> my $step=Math::BigFloat->new(1);
> $step->bdiv($nr);
> print "$step \t";
> my $sum=0;
> for (1..$nr){$sum=$sum+$step};
> print "$sum \n";
>
> Davon, das die Berechung schnell gehen soll,
> war ja nicht die Rede :)

Ja, ja Frank, echt guter Vorschlag!

Und dann geht der Stefan her, packt an den Divisor noch ein paar Nullen
mehr ran, kommt an Ostern wieder und sagt: Perl rechnet nicht nur
ungenau, es dauert auch noch eine Ewigkeit, bis das falsche Ergebnis kommt!

Schönen Aschermittwoch
Karlheinz

(nix für ungut Stefan, ist natürlich eine bösartige Unterstellung)
Karlheinz Weindl [ Mi, 01 März 2006 18:59 ] [ ID #1210557 ]

Re: Genauigkeit in Perl

Karlheinz Weindl wrote:
> Frank Seitz schrieb:

[Rechnen mit beliebig großen Gleitkommazahlen]

> Ja, ja Frank, echt guter Vorschlag!
>
> Und dann geht der Stefan her, packt an den Divisor noch ein paar Nullen
> mehr ran, kommt an Ostern wieder und sagt: Perl rechnet nicht nur
> ungenau, es dauert auch noch eine Ewigkeit, bis das falsche Ergebnis kommt!

Das sehe ich nicht. Weder, dass er im Fall einer großen Zahl nochmal
wiederkommt, noch dass er ein falsches Ergebnis erhält.

my $nr=Math::BigFloat->new(250000000000000000000000000000000000 00000000000000);
my $step=Math::BigFloat->new(1);
$step->bdiv($nr);
print "$nr\n$step\n";
__END__
25000000000000000000000000000000000000000000000000
0.00000000000000000000000000000000000000000000000004

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Frank Seitz [ Mi, 01 März 2006 19:38 ] [ ID #1210558 ]

Re: Genauigkeit in Perl

On Wed, 01 Mar 2006 17:15:40 +0100, Stefan Kristukat
<stefan.kristukat [at] epfl.ch> wrote:

>Hallo zusammen,
>
>hier mein Code. Am Ende sollte fuer $sum 1.0 rauskommen, tut es aber
>nicht. Es kommt mehr raus - abhängig von der Genauigkeit. Jetzt rechnet
>Perl aber schon per default mit doppelter Genauigkeit. Wie kann ich das
>Problem vermeiden?
(
Alles in ints verwandeln, ggf Bigint verwenden.
Dann mit modulo-Arithmetik zurückrechnen.

Alternativ: Mit Strings arbeiten und die Rechenoperationen auf
Stringoperationen zurückführen.

Oder mit Brüchen rechnen: Math::Fraction

Oder
use const eps => Wähle eine zahl genügende klein
definiere eine Zahl $a als $a=($a-eps,$a+eps).
)
Und Wolfbook p 472 und TPJ No 8 "unreal Numbers " von T.Phoenix lesen.



----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= East/West-Coast Server Farms - Total Privacy via Encryption =---
xxx[1] [ Sa, 11 März 2006 17:22 ] [ ID #1225293 ]
Perl » de.comp.lang.perl.misc » Genauigkeit in Perl

Vorheriges Thema: RegExp matcht nur 2. Alternative - ratlos
Nächstes Thema: Filehandles schliessen...