🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.programming
Article #215645

Re: Porównywanie liczb, double float

#215645
From: AK
Date: Sat, 13 Jul 2019 07:21
53 lines
2766 bytes
On 2019-07-12 07:27, DMR wrote:
>> Zamieszcze tu po raz 473 w ciagu 20 lat podstawową formułkę
>> (Ba! KANON!)
> 
> To ja poprosiłbym o jakiś patent na odporne na zaokrąglenia rozdzielenie części całkowitej i ułamkowej w zmiennej typu double.
> 
>> ponaglenia o pilną zapłatę 0.00PLN
> 
> No właśnie.
> Przykładowo, muszę zrobić: 12345.6789 zł -> 12345 zł 68 gr
> 
> Wiadomo:
> 
> double suma, f;
> int zlote, grosze;
> 
>     ...
> 
>     suma += 0.005;
> 
>     zlote = (int)suma;
>     f = suma - zlote;
>     grosze = (int)(f * 100.0);
> 
> Problemy mogą pojawić w przypadku wartości praktycznie równych wartościom całkowitym.
> Gdyby na skutek jakichś zaokrągleń wartość f okazała się ujemna, to nie ma problemu - (int) i tak "dociągnie" ją do zera.
> 
> Gorzej, gdyby np. suma = 1234.9999999999999997, za to teoretycznie f = 0.9999999999999997 za sprawą zabłąkanego bitu na końcu przeskoczyła na f = 1.0000000000000001.
> Wtedy wyjdzie 1234 zł 100 gr...
> 
> Chyba, że nie potrzebnie się martwię.
> Testowałem to wielokrotnie dla miliardów złośliwie wygenerowanych danych "z pogranicza" - ani razu się nie wywaliła.
> 
> No, ale... :-)

Proszę bardzo.
To jest drugi KANON (zaokraglanie do int-a):

W Pythonie tak:
     grosze, zlote = math.modf(amount)
     zlote  = int(abs(zlote) + 0.5)
     grosze = int(abs(grosze) * 100.0 + 0.5)

W C/C++ cuś w rodzaju:
     double zlote_fp;
     double grosze_fp = modf(amount, &zlote_fp);
     long zlote  = long(fabs(zlote_fp) + 0.5);
     int  grosze = int(fabs(grosze_fp) * 100.0 + 0.5);

PS: Wazne jest to + 0.5. Jeszcze z Algolu pamietam:)
integer := ENTER(float + 0.5)

AK
Technical Details
Message-ID: <qgc0p6$1jf$1@gioia.aioe.org>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!takemy.news.telefonica.de!telefonica.de!weretis.net!feeder7.news.weretis.net!news.mixmin.net!aioe.org!.POSTED.hz5Li9JkiJv11OHzJkoZfQ.user.gioia.aioe.org!not-for-mail
References: <qdqqh6$n2f$1@dont-email.me> <5d00f035$0$15194$426a74cc@news.free.fr> <5d011217$0$17348$65785112@news.neostrada.pl> <qe65vo$18po$1@gioia.aioe.org> <5b09d1e0-1ed9-4a3c-851e-29cbf826cb3a@googlegroups.com>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!takemy.news.telefonica.de!telefonica.de!weretis.net!feeder7.news.weretis.net!news.mixmin.net!aioe.org!.POSTED.hz5Li9JkiJv11OHzJkoZfQ.user.gioia.aioe.org!not-for-mail
From: AK <nobody@nowhere.net>
Newsgroups: pl.comp.programming
Subject: Re: Porównywanie liczb, double float
Date: Sat, 13 Jul 2019 09:21:07 +0200
Organization: Aioe.org NNTP Server
Lines: 53
Message-ID: <qgc0p6$1jf$1@gioia.aioe.org>
References: <qdqqh6$n2f$1@dont-email.me> <5d00f035$0$15194$426a74cc@news.free.fr> <5d011217$0$17348$65785112@news.neostrada.pl> <qe65vo$18po$1@gioia.aioe.org> <5b09d1e0-1ed9-4a3c-851e-29cbf826cb3a@googlegroups.com>
NNTP-Posting-Host: hz5Li9JkiJv11OHzJkoZfQ.user.gioia.aioe.org
Mime-Version: 1.0
X-Complaints-To: abuse@aioe.org
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.7.2
X-Notice: Filtered by postfilter v. 0.9.2
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit