🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.perl
Article #52166

Re: niedokładność biginta

#52166
From: Stachu 'Dozzie' K.
Date: Wed, 19 Jan 2011 22:11
100 lines
3197 bytes
On 2011-01-19, Maciej Misiak <grizzley@poczta.onet.pl> wrote:
> Help.
>
> #!perl -l
>
> use bigint;
>
> ($x,$y)=split/ /, "26315789473684210 5";
> ($l,$m)=($y.$x,$x.$y);
> $xx=$l/$m;
> print$l,' ', $m,' ',$xx, ' ', $xx*$m, ' ', $xx*$m-$l;
> die if $xx*$m!=$l;
>
>
> Ja mam w wyniku die, choć nie powinienem:
> 526315789473684210 263157894736842105 2 5.26315789473684e+017 64
> Died at p168test.pl line 9.

No też bym się czegoś innego spodziewał. Przepisałem twój skrypt na
nieco bardziej widoczny:

#v+
#!perl -l

use bigint;

my ($x, $y) = split / /, "26315789473684210 5";
my ($l, $m) = ($y . $x, $x . $y);

print "L = ", $l;
print "M = ", $m;

my $xx = $l / $m;
print "F (= L/M) = ", $xx;
print "F * M = ", $xx * $m;
print "F * M - L (=~ 0) = ", $xx * $m - $l;
#v-

Output:
#v+
L = 526315789473684210
M = 263157894736842105
F (= L/M) = 2
F * M = 5.26315789473684e+17
F * M - L (=~ 0) = 64
#v-

Czyli z jakiegoś powodu "$xx * $m" jest zamieniane na floating point.

#v+
print "F * M = ", Math::BigInt->bmul($xx, $m);
print "F * M - L (=~ 0) = ", Math::BigInt->bmul($xx, $m) - $l;
#v-
To odpowiednio wypisuje:
#v+
F * M = 526315789473684210
F * M - L (=~ 0) = 0
#v-

Strzał prawie w ciemno: a na pewno $l i $m są typu Math::BigInt?
#v+
#!perl -l

use bigint;

my ($x, $y) = split / /, "26315789473684210 5";
my ($l, $m) = ($y . $x, $x . $y);

print $l->isa("Math::BigInt");
print $m->isa("Math::BigInt");
#v-

Bingo!

#v+
Can't call method "isa" without a package or object reference at ./test.pl line 8.
#v-

Znaczy: póki $l i $m są stringami, nie mogą być podmiotem operacji,
które wykonuje `use bigint'. Zamiana $l i $m na na-pewno-liczby pomaga:

#v+
#!perl -l

use bigint;

my ($x, $y) = split / /, "26315789473684210 5";
my ($l, $m) = ($y . $x, $x . $y);
$l += 0;
$m += 0;

my $xx = $l / $m;

die if $xx * $m != $l;
print "równe!";
#v-

-- 
Secunia non olet.
Stanislaw Klekot
Technical Details
Message-ID: <ih7nid$rjs$1@solani.org>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.nask.pl!news.nask.org.pl!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsfeed.straub-nv.de!weretis.net!feeder3.news.weretis.net!news.solani.org!not-for-mail
References: <ih7lun$ctt$1@news.onet.pl>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.nask.pl!news.nask.org.pl!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsfeed.straub-nv.de!weretis.net!feeder3.news.weretis.net!news.solani.org!not-for-mail
From: "Stachu 'Dozzie' K." <dozzie@go.eat.some.screws.spammer.invalid>
Newsgroups: pl.comp.lang.perl
Subject: Re: niedokładność biginta
Date: Wed, 19 Jan 2011 22:11:25 +0000 (UTC)
Organization: solani.org
Lines: 100
Message-ID: <ih7nid$rjs$1@solani.org>
References: <ih7lun$ctt$1@news.onet.pl>
Mime-Version: 1.0
X-Trace: solani.org 1295475085 28284 eJwFwYEBwCAIA7CbKC3qOdLJ/ycsUVaUF0tFjWYNmuKXtyYjtGkkA6efETuvsbo07QM/4QcNyRDG (19 Jan 2011 22:11:25 GMT)
X-Complaints-To: abuse@news.solani.org
NNTP-Posting-Date: Wed, 19 Jan 2011 22:11:25 +0000 (UTC)
X-User-ID: eJwFwYERACEIA7CVBNuC4zye3X+ET7gVugVRoOlT5UEL2vlCD9dCJWSvx/B8ndXkWRoJ8wMLDBBg
Cancel-Lock: sha1:fuRO/8VNQS8K9pvdqmfjh94g5C4=
User-Agent: slrn/pre0.9.9-111 (Linux)
X-NNTP-Posting-Host: eJwFwQkBwDAIA0BLUAh0cngW/xJ6BwuNSQ+EgyDrmma01e6cFkGTf+YURlaoovad41u2mLsPLqIRpg==
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit