🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.asm
Article #2555

Re: [1/3 NTG] C - Optymalizacje wstawkami

#2555
From: "Bogdan (bogdro)
Date: Tue, 19 Feb 2019 19:58
59 lines
2095 bytes
W dniu 17.02.2019 o 21:17, DMR pisze:

[...]

> inline void DoubleToString(double dValue, char* cBuffer)
> {
> double dRnd;
> unsigned int iReal, val;
> char *ptr, *dot;
>
>    ptr = cBuffer + 15;
>    dot = cBuffer + 10;
>    *ptr = '\0';
>    *dot = '.';
>
>    dRnd = dValue + 0.00005; // zaokrąglenie czwartej cyfry
>    iReal = (int)dRnd;
>
>    val = (int)((dRnd - iReal) * 10000.0); // część ułamkowa *)
>    while (val)
>    {
>       *--ptr = char(val % 10) | '0';
>       val /= 10;
>    }


[...]

> Boję się tylko o jedno - że w linijce *) w jakimś perfidnym przypadku (liczby praktycznie całkowitej) pojawią się mikroskopijne błędy zaokrągleń, które jednak spowodują "przekręcenie" części ułamkowej względem rzeczywistej i zamiast 10.0000 wyjdzie 10.9999, czy jakoś tak.


 Fakt, trochę bym się bał wyświetlać liczbę, którą sam zmieniłem w
kodzie jako tą, którą dostałem. A że lubię znajdować przypadki
wyjątkowe, niech dValue = 1,999999 (pomijając fakt, czy da się taką
liczbę dokładnie reprezentować binarnie, pewnie dowolna bliska liczba
też wystarczy). Wtedy, jeśli dobrze liczę:
- dRnd = dValue + 0.00005 = 2,000049
- iReal = (int)dRnd = 2
- dRnd - iReal = 0,000049
- (dRnd - iReal) * 10000.0 = 4,9
- val = (int)((dRnd - iReal) * 10000.0) = 4
- wyświetlasz "4" i dopełniasz zerami,
- wyświetlasz iReal (2)
- dostałeś 1,999999 jako parametr, wyświetliłeś 2,00004 :)

Pewnie da się coś lepszego wymyślić, ale na szybko:

 iReal = ((int)(dValue * 100000 + 5)) / 100000; // część całkowita
 val = ((dValue - (int)dValue) * 100000 + 5) / 10;

 W części ułamkowej mnożymy przez sto (a nie dziesięć) tysięcy,
dodajemy 5, aby zaokrąglić, i dzielimy przez 10, aby dostać 4 cyfry
"zza przecinka" jako liczbę całkowitą.


--
Pozdrawiam/Regards - Bogdan                     (GNU/Linux & FreeDOS)
Kurs asemblera x86 (DOS, GNU/Linux):            http://bogdro.evai.pl
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
www.Xiph.org www.TorProject.org  Soft(EN): http://bogdro.evai.pl/soft

Message-ID: <5c6c51d8$0$484$65785112@news.neostrada.pl>
Path: polish.pugleaf.net!archive.newsdeef.eu!apf1.newsdeef.eu!not-for-mail
References: <30292520-12bd-49f0-b5ce-39c9af378a4c@googlegroups.com> <5c5b41d7$0$501$65785112@news.neostrada.pl> <781a3ad8-10bb-42aa-939f-dc6c11efa783@googlegroups.com> <5c5df439$0$476$65785112@news.neostrada.pl> <5e988bac-236b-42c4-8f94-87c5586d58d1@googlegroups.com> <5c632cc2$0$492$65785112@news.neostrada.pl> <17dc9fb7-38b2-4278-a1fc-d7b9c4746e70@googlegroups.com> <5c697caa$0$476$65785112@news.neostrada.pl> <c77eea4d-735a-429d-9cb1-a792378213b3@googlegroups.com>