Groups | Search | Server Info | Login | Register


Groups > pl.comp.lang.asm > #21

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

Newsgroups pl.comp.lang.asm
Date 2019-02-20 00:53 -0800
References (5 earlier) <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> <5c6c51d8$0$484$65785112@news.neostrada.pl>
Message-ID <1b525740-eca4-48ed-be54-16aa0265d7b3@googlegroups.com> (permalink)
Subject Re: [1/3 NTG] C - Optymalizacje wstawkami
From DMR <mezzogm@gmail.com>

Show all headers | View raw


> - dostałeś 1,999999 jako parametr, wyświetliłeś 2,00004 :) 


Na początku dodałem 0.00005, więc niby co innego miałbym otrzymać? ;-)
A dodałem tę piątkę na piątym, żeby sobie po "urżnięciu" int-em uporządkować CZTERY miejsca po przecinku.
Cztery, bo akurat tak chcę, gdybym chciał pięciu, dodałbym 0.000005 itd.
Ale nie w tym problem...



> jeśli dobrze liczę


Źle i do tego tendencyjnie... ;-)



> - dRnd - iReal = 0,000049
> - (dRnd - iReal) * 10000.0 = 4,9


(dRnd - iReal) * 10000.0 = 0.49
val = (int)((dRnd - iReal) * 10000.0) = 0

Wyświetlam iReal i "dopełniam" czterema zerami.

Czyli ostatecznie wyszła konwersja: 1.99999 -> 2.0000 
Tu wszystko gra i koliduje. :-)



> (pomijając fakt, czy da się taką liczbę dokładnie
> reprezentować binarnie, pewnie dowolna bliska liczba
> też wystarczy).


O, to, to właśnie!
Boję się, że jakiś przestawiony bit gdzieś na n-tym miejscu rozwali mi cały sens wyliczenia ułamkowej "reszty": F = (dRnd - iReal) * 10000.0
To znaczy - już się tak nie boję, bo mnie to gadulstwo naprawdę inspiruje. ;-)

Najłatwiej byłoby przejść na 64 bity - tam int ma "pojemność" 18 cyfr, więc obsłużyłby doubla w pełnym zakresie dokładności - wystarczyłoby go wymnożyć do wszystkich cyfr przed przecinkiem, JEDNYM CIĘCIEM przerobić na int-a i zrobić "normalne" itoa, wstawiając tylko przecinek gdzie tam trzeba.
Niestety, int 32-bitowy "mieści" tylko 9 cyfr, więc jeśli cyfr ma być więcej, to cięcia muszą być dwa - niezależne od siebie, i może to narobić kłopotów...

W "standardowej" sytuacji ewentualne błędy zaokrągleń zmienią mi co najwyżej ostatnią cyfrę F, więc nie jest to żaden problem, tym bardziej, że konwertowana wartość dValue balansująca na granicy połówki obcinanej cyfry w pełni taki efekt rozgrzesza.

Mniej ciekawie wygląda to dla wartości dValue w zakresie liczb całkowitych, gdzie teoretycznie dRnd = iReal, ale ze względu na różnice reprezentacji ta równość niekoniecznie musi zachodzić ściśle.
Sama liczba 0.00005 przecież też nie ma ścisłej reprezentacji:
http://www.binaryconvert.com/result_double.html?decimal=048046048048048048053

Jeżeli po "obcięciu" części całkowitej wartość reszty F będzie praktycznie równa zeru, to nie ma problemu - int ucina w kierunku zera, więc śladową "fluktuację" reszty F i tak dociągnie do zera, niezależnie od jej znaku.
Gorzej dla liczb "prawie całkowitych" (typu 3714.9999999999999997...) gdzie int może prawidłowo obciąć część całkowitą 3714, ale reszta 0.9999999999999997... za sprawą jakiegoś zabłąkanego bitu przeskoczy na 1.0000000000000001...
Optymistyczne jest to, że taki przypadek można łatwo wyłapać (dla czterech cyfr: val > 9999).

A może znowu niepotrzebnie się martwię?
Trochę się to wszystko komplikuje, więc może lepiej powrócić do "czystej" koncepcji "ręcznego" rozprawienia się z problemem:
http://0x80.pl/articles/convert-float-to-integer.html
Ale o ile w przypadku float-ów nie ma problemu, to w double mantysa ma długość 52 bitów, więc znowu - na 64 bitach można zastosować kalkę rozwiązania, natomiast przy 32 bitach problem się piętrzy - tzn. na pewno jest rozwiązywalny, tylko wcale nie jest pewne, że te obejścia nie przegrają już na starcie z "natywnym" zachowaniem koprocesora.


Wypadałoby chyba zmienić tytuł wątku... ;-)

Back to pl.comp.lang.asm | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

[1/3 NTG] C - Optymalizacje wstawkami DMR <mezzogm@gmail.com> - 2019-02-04 09:19 -0800
  Re: [1/3 NTG] C - Optymalizacje wstawkami "Bogdan (bogdro)" <bogdan@poczta.gazeta.pl> - 2019-02-06 21:21 +0100
    Re: [1/3 NTG] C - Optymalizacje wstawkami DMR <mezzogm@gmail.com> - 2019-02-08 09:31 -0800
      Re: [1/3 NTG] C - Optymalizacje wstawkami "Bogdan (bogdro)" <bogdan@poczta.gazeta.pl> - 2019-02-08 22:27 +0100
        Re: [1/3 NTG] C - Optymalizacje wstawkami mezzogm@gmail.com - 2019-02-11 07:56 -0800
          Re: [1/3 NTG] C - Optymalizacje wstawkami "Bogdan (bogdro)" <bogdan@poczta.gazeta.pl> - 2019-02-12 21:23 +0100
            Re: [1/3 NTG] C - Optymalizacje wstawkami DMR <mezzogm@gmail.com> - 2019-02-12 15:07 -0800
            Re: [1/3 NTG] C - Optymalizacje wstawkami "Bogdan (bogdro)" <bogdan@poczta.gazeta.pl> - 2019-02-13 20:38 +0100
        Re: [1/3 NTG] C - Optymalizacje wstawkami DMR <mezzogm@gmail.com> - 2019-02-12 08:04 -0800
          Re: [1/3 NTG] C - Optymalizacje wstawkami "Bogdan (bogdro)" <bogdan@poczta.gazeta.pl> - 2019-02-12 21:29 +0100
            Re: [1/3 NTG] C - Optymalizacje wstawkami DMR <mezzogm@gmail.com> - 2019-02-13 10:12 -0800
              Re: [1/3 NTG] C - Optymalizacje wstawkami "Bogdan (bogdro)" <bogdan@poczta.gazeta.pl> - 2019-02-17 16:24 +0100
                Re: [1/3 NTG] C - Optymalizacje wstawkami DMR <mezzogm@gmail.com> - 2019-02-17 12:17 -0800
                Re: [1/3 NTG] C - Optymalizacje wstawkami "Bogdan (bogdro)" <bogdan@poczta.gazeta.pl> - 2019-02-19 19:58 +0100
                Re: [1/3 NTG] C - Optymalizacje wstawkami DMR <mezzogm@gmail.com> - 2019-02-20 00:53 -0800
                Re: [1/3 NTG] C - Optymalizacje wstawkami DMR <mezzogm@gmail.com> - 2020-01-12 09:27 -0800
  Re: [1/3 NTG] C - Optymalizacje wstawkami DMR <mezzogm@gmail.com> - 2019-06-06 02:27 -0700
    Re: [1/3 NTG] C - Optymalizacje wstawkami "Bogdan (bogdro)" <bogdan@poczta.gazeta.pl> - 2019-06-08 23:26 +0200
      Re: [1/3 NTG] C - Optymalizacje wstawkami DMR <mezzogm@gmail.com> - 2019-06-10 09:05 -0700

csiph-web