Re: [speagram] =?unknown-8bit?Q?Obs=B3ug?= =?unknown-8bit?Q?a?= liczb w kombinatorach.
Status: Alpha
Brought to you by:
lukaszkaiser
From: Lukasz K. <ka...@te...> - 2004-09-04 00:19:51
|
Hej. > digitsum (nat_cons (m, d)) > > jest po rzutowaniu przerabiany na: > > digitsum (nat_float (nat_cons (m, d), 1)) > > Ca??y problem polega na tym, ??e nie istnieje liczba ca??kowita > spe??niaj??ca ten warunek. Jaki warunek ? Choc rzeczywiscie, liczenie sumy cyfr liczb typu floating point jest dosc malo powszechnym zajeciem. Ale po co je liczysz? Moze jednak zadeklarowac typ argumentu digitsum jako integers i w ten sposob ominac problem (dodajac tez +, -, itp. dla integers). > Samo nat_cons sugeruje, ??e liczba jest wi??ksza od 10, ale > wyk??adnik == 1 sprawia, ??e liczba musi by?? jednocyfrowa. Rzeczywiscie, rzutowanie jest zle, musze zmienic funkcje liczaca wykladnik. Oczywiscie potrzebuje do tego wlasciwie zdefiniowanego digitsum i +, sprobuje je napisac niedlugo. Ale obsluge 3 roznych + to juz sam musisz dodac do handlerow. > Jest spory problem z precyzj?? oblicze??. Najpierw problem. Niech r > b??dzie liczb?? rzeczywist??. Jako term r jest reprezentowane w postaci: > > r = cons_float (m, c) > > co oznacza: > > r = 0.m * 10 ^ c > > ??atwo jest obliczy?? c jako: > > c = floor (1 + log (r)) > > Niestety gorzej jest z m. ??ukasz zaproponowa??, ??eby m oblicza?? ze > sta???? precyzj??. Dla ustalenia uwagi przyjmijmy, ??e precyzja jest 2, > czyli bierzemy pod uwag?? tylko 2 miejsca po przecinku. Wtedy: > > m = floor (10^2 * (r / 10^c)) Pierwsza uwaga: jesli r = 0.m * 10^c i mamy r i c to nie ulega zadnej watpliwosci, ze 0.m = r / 10^c > Przyk??ady: > r = 0.70 --> c = 0, m = 7 wydaje sie byc ok ... > r = 1.07 --> c = 1, m = 10 0.10 * 10^1 = 1.0 poprawnie > r = 7.00 --> c = 1, m = 70 tez poprawnie ... OK, ja chyba rozumiem problem - mozna sobie wywalic zera na koncu, bo tak to jest z liczbami po przecinku. Kodowanie jest niejednoznaczne po prostu. Moja propozycja jest taka, zeby zmienic kodowanie na: cons_float (m, c) = m * 10^c Nie tracimy w ten sposob zadnej dokladnosci, natomiast rzeczy sie robia latwiejsze. Nadal mamy ten sam problem z niejednoznacznoscia, ale teraz moga przynajmniej zrzutowac m na m * 10^0. No a przy kodowaniu r musisz niestety policzyc cyfry znaczace po kolei. Najbardziej znaczaca cyfra r to chyba jest d1 (r) = floor (r / 10^floor (log (r))) przyklad: r = 9002 d1 (r) = [9002 / 10^4] = 9 dalej trzeba chyba najpierw wywalic te 9000 z gory: r' = r - d1(r) * 10^floor (log(r))) -- 2 no i potem policzyc tego floor (log(r)) - 1 cyfre: d2(r) = floor (r' / 10^floor (log(r) - 1)) Po takim glupim przykladzie widac, ze to sie chyba mozna tak, zeby sobie dzielic przez 10^odpowiedniej i reszte brac mod 10. kth_digit_dividor (r, k) = 10^ (floor (log (r)) - k + 1) kth_digit (r, k) = floor (r / kth_digit_dividor (r, k)) % 10 Co myslisz ? - lk |