🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.python
9 messages
9 total messages Started by moozg Wed, 25 Dec 2002 17:10
Bledne zaokraglanie ulamkow
#445
Author: moozg
Date: Wed, 25 Dec 2002 17:10
18 lines
1682 bytes
Czy ktos sie spotkal z blednym zaokraglaniem ulamkow w pythonie?
konkretnie chodzi o funkcje round.
Kiedy podaje na wejsciu jeden parametr (np. round (32.26351263561) )
otrzymuje prawidlowy wynik, czyli 32.0
Ale jesli wywoluje funkcje tak: round(32.26351263561, 2) co ma
zaokraglic liczbe do dwoch miejsc za przecinkiem otrzymuje cos
takiego:  31.969999999999999
zamiast 8.50, mam 8.4900000000000002

Aha - nie probujcie zaokraglic tej liczby ktora tu podalem, jesli
wpisuje jawnie liczbe ktora chce zaokraglic to wszystko jest ok.
Blad pojawia sie wtedy, kiedy zaokraglam wynik pewnych obliczen.
Podejrzewam ze python pamieta liczby z wieksza precyzja niz je
wyswietla i dlatego recznie nie potrafie powtorzyc tego bledu.

Niestety potrzebuje liczb z dokladnoscia 2 miejsc za przecinkiem i w
tej chwili nie mam idei co z tym zrobic. Wolalbym unikac konwersji na
tekst, wycinania zbednej czesci ulamka i powrot na float.
Bledne zaokraglanie ulamkow
#446
Author: moozg
Date: Wed, 25 Dec 2002 17:30
22 lines
1316 bytes
Errata :)
Problem nie lezy w zaokraglaniu, ale wyswietlaniu ulamkow.
Nie wiem z czego to wynika, ale ulamki raz sa wyswietlane prawidlowo,
a innym razem blednie.
Ten programik:

a = 35.86
print a
l = (a,a,a)
print l

wyswietla u mnie cos takiego:

35.86
(35.859999999999999, 35.859999999999999, 35.859999999999999)


Chyba dosc dziwne?
Wiem ze w przypadku print a, do konwersji na tekst jest uzywana metoda
__str__, a w przypadku print (a,a,a) metoda __repr__.

Co nie zmienia faktu ze wynik jest bledny
Re: Bledne zaokraglanie ulamkow
#447
Author: Krzysztof Stachlewski
Date: Wed, 25 Dec 2002 17:34
9 lines
1082 bytes
"moozg" <moozg@k2studio.com.pl> wrote in message
news:3e09ea7a.3571112@news.icpnet.pl...

> Chyba dosc dziwne?

Ani trochę. Poczytaj o reprezentacji liczb
zmiennoprzecinkowych.

Stach
Re: Bledne zaokraglanie ulamkow
#449
Author: Marcin 'Qrczak' Kowalczyk
Date: Wed, 25 Dec 2002 17:42
21 lines
1869 bytes
Wed, 25 Dec 2002 17:10:15 GMT, moozg <moozg@k2studio.com.pl> pisze:

> Ale jesli wywoluje funkcje tak: round(32.26351263561, 2) co ma
> zaokraglic liczbe do dwoch miejsc za przecinkiem otrzymuje cos
> takiego:  31.969999999999999

Bo 31.97 nie jest reprezentowalne w typie double w C, czyli też w typie
float w Pythonie. To, co dostajesz, jest najlepszym przybliżeniem.
Po przetłumaczeniu na ułamek dziesiętny widać, że to ciut mniej
niż 31.97; następna reprezentowalna wartość jest ciut większa niż
31.97. Więc co chcesz uzyskać? Dokładna liczba 31.97 w typie float
nie istnieje.

str pokazuje o jedną mniej cyfr niż repr, więc str od Twojej liczby
da '31.97'. Więc nie przejmuj się, że jak się ją wpisze w prompcie,
to widać więcej cyfr (to jest wyświetlane przez repr).

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: Bledne zaokraglanie ulamkow
#448
Author: Marcin 'Qrczak' Kowalczyk
Date: Wed, 25 Dec 2002 20:24
11 lines
1324 bytes
Wed, 25 Dec 2002 17:30:41 GMT, moozg <moozg@k2studio.com.pl> pisze:

> Wiem ze w przypadku print a, do konwersji na tekst jest uzywana metoda
> __str__, a w przypadku print (a,a,a) metoda __repr__.

No właśnie. Stąd ta różnica.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: Bledne zaokraglanie ulamkow
#450
Author: Marcin Wojtczuk
Date: Sat, 28 Dec 2002 02:43
52 lines
2420 bytes
Marcin 'Qrczak' Kowalczyk claimed:
> Wed, 25 Dec 2002 17:10:15 GMT, moozg <moozg@k2studio.com.pl> pisze:
> 
>> Ale jesli wywoluje funkcje tak: round(32.26351263561, 2) co ma
>> zaokraglic liczbe do dwoch miejsc za przecinkiem otrzymuje cos
>> takiego:  31.969999999999999
> 
> Bo 31.97 nie jest reprezentowalne w typie double w C,

Bzdura:
Po pierwsze:
31,97 = $1F.61 = $1.F61 * 16.

Znak: 0
Cecha: $F61
Mantysa: 4

Więc chyba 64 bity starczą ? :)

Po drugie:
#v+
   /* Number of decimal digits of precision in a double */
#define DBL_DIG 15
#v-
(cytat z float.h). Czyli każda liczba o mniej niż 15 cyfrach po przecinku
jest w double reprezentowana DOKŁADNIE.

> czyli też w typie
> float w Pythonie. To, co dostajesz, jest najlepszym przybliżeniem.

Python ma jakieś niejasne zasady precyzji artmetyki. Ktoś wie jakie ?

> Po przetłumaczeniu na ułamek dziesiętny widać, że to ciut mniej
> niż 31.97; następna reprezentowalna wartość jest ciut większa niż
> 31.97. Więc co chcesz uzyskać? Dokładna liczba 31.97 w typie float
> nie istnieje.

Taak ?
#v+
   /* Number of decimal digits of precision in a float */
#define FLT_DIG 6
#v-

> str pokazuje o jedną mniej cyfr niż repr, więc str od Twojej liczby
> da '31.97'. Więc nie przejmuj się, że jak się ją wpisze w prompcie,
> to widać więcej cyfr (to jest wyświetlane przez repr).

Fajnie by było wiedzieć jaką logiką kieruje się tutaj python.

-- 
    [ http://www.stringi.com/viper/ ] 
  All good things come to those who wait
Re: Bledne zaokraglanie ulamkow
#451
Author: Lukasz Kuznia
Date: Sat, 28 Dec 2002 23:29
54 lines
2518 bytes
> Bzdura:
> Po pierwsze:
> 31,97 = $1F.61 = $1.F61 * 16.
>
> Znak: 0
> Cecha: $F61
> Mantysa: 4

Proponuje troche poczytac na temat reprezentacji liczb zmiennoprzecinkowych
w maszynach cyfrowych (mantysa, cecha etc. w fl)

> Po drugie:
> #v+
>    /* Number of decimal digits of precision in a double */
> #define DBL_DIG 15
> #v-
> (cytat z float.h). Czyli każda liczba o mniej niż 15 cyfrach po przecinku
> jest w double reprezentowana DOKŁADNIE.

Znaczenie tej stalej mozna znalezc w opisie ISO C, ale zareczam ze nie jest
tak kolorowo jak piszesz.

> > czyli też w typie
> > float w Pythonie. To, co dostajesz, jest najlepszym przybliżeniem.
>
> Python ma jakieś niejasne zasady precyzji artmetyki. Ktoś wie jakie ?


Ma bardzo jasne i klarowne. Tylko rzeczywistosc arytmetyki fl wprawia w
zdumienie.

>
> > Po przetłumaczeniu na ułamek dziesiętny widać, że to ciut mniej
> > niż 31.97; następna reprezentowalna wartość jest ciut większa niż
> > 31.97. Więc co chcesz uzyskać? Dokładna liczba 31.97 w typie float
> > nie istnieje.
>
> Taak ?
> #v+
>    /* Number of decimal digits of precision in a float */
> #define FLT_DIG 6
> #v-

ISO C
> > str pokazuje o jedną mniej cyfr niż repr, więc str od Twojej liczby
> > da '31.97'. Więc nie przejmuj się, że jak się ją wpisze w prompcie,
> > to widać więcej cyfr (to jest wyświetlane przez repr).
>
> Fajnie by było wiedzieć jaką logiką kieruje się tutaj python.

repr wyswietla 17 cyfr znaczacych, str 12

Pozdrawiam,
Lukasz Kuznia
Re: Bledne zaokraglanie ulamkow
#452
Author: Marcin 'Qrczak' Kowalczyk
Date: Sun, 29 Dec 2002 10:43
64 lines
3477 bytes
Sat, 28 Dec 2002 03:43:52 +0100, Marcin Wojtczuk <fastviper@telkab.pl> pisze:

>> Bo 31.97 nie jest reprezentowalne w typie double w C,
> 
> Bzdura:
> Po pierwsze:
> 31,97 = $1F.61 = $1.F61 * 16.

Nieprawda. $1F.61 = 31.37890625, a nie 31.97. 97/100 nie jest
reprezentowalne ułamkiem z mianownikiem będącym potęgą dwójki,
więc nie jest reprezentowalne w dwójkowym zmiennopozycyjnym typie
o żadnej dokładności. Tak jak 1/3 nie jest reprezentowalne w systemie
dziesiętnym w żadnej skończonej liczbie cyfr.

>    /* Number of decimal digits of precision in a double */
> #define DBL_DIG 15
> #v-
> (cytat z float.h). Czyli każda liczba o mniej niż 15 cyfrach po przecinku
> jest w double reprezentowana DOKŁADNIE.

Bzdura. Znaczy to tylko tyle, że dla każdej takiej liczby istnieje
taka wartość typu double, która zaokrąglona do 15 cyfr dziesiętnych
da tę liczbę z powrotem.

> Python ma jakieś niejasne zasady precyzji artmetyki. Ktoś wie jakie ?

Takie jak C.

>> Po przetłumaczeniu na ułamek dziesiętny widać, że to ciut mniej
>> niż 31.97; następna reprezentowalna wartość jest ciut większa niż
>> 31.97. Więc co chcesz uzyskać? Dokładna liczba 31.97 w typie float
>> nie istnieje.
> 
> Taak ?
> #v+
>    /* Number of decimal digits of precision in a float */
> #define FLT_DIG 6

Mam na myśli float Pythona, czyli double C, ale sytuacja jest
analogiczna.

>> str pokazuje o jedną mniej cyfr niż repr, więc str od Twojej liczby
>> da '31.97'. Więc nie przejmuj się, że jak się ją wpisze w prompcie,
>> to widać więcej cyfr (to jest wyświetlane przez repr).
> 
> Fajnie by było wiedzieć jaką logiką kieruje się tutaj python.

str: żeby liczba o małej liczbie dziesiętnych cyfr po przecinku była
pokazana właśnie w taki sposób - bo najprawdopodobniej taka liczba
powstała przez zaokrąglenie odpowiedniej liczby dziesiętnej.

repr: żeby można było dokładnie odtworzyć liczbę z jej tekstowej
reprezentacji.

Można było zrobić lepiej, tak jak to robi np. Glasgow Haskell Compiler,
co jest trudniejsze w realizacji. Mianowicie pokazywać zawsze liczbę
w 15 cyfrach dziesiętnych, o ile konwersja takiej reprezentacji
z powrotem na double dałaby ten sam wynik, i w 16, jeśli nie. Daje
to obie zalety równocześnie.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: Bledne zaokraglanie ulamkow
#453
Author: Marcin Wojtczuk
Date: Sun, 29 Dec 2002 21:21
30 lines
2027 bytes
Marcin 'Qrczak' Kowalczyk claimed:
> Sat, 28 Dec 2002 03:43:52 +0100, Marcin Wojtczuk <fastviper@telkab.pl> pisze:
> 
>>> Bo 31.97 nie jest reprezentowalne w typie double w C,
>> 
>> Bzdura:
>> Po pierwsze:
>> 31,97 = $1F.61 = $1.F61 * 16.
> 
> Nieprawda. $1F.61 = 31.37890625, a nie 31.97. 97/100 nie jest
> reprezentowalne ułamkiem z mianownikiem będącym potęgą dwójki,

Ha! Rzeczywiście błąd. Chyba późna godzina była :>
Nawet wiem dlaczego: 97 nie dzieli się całkowicie przez 25 :)

>>    /* Number of decimal digits of precision in a double */
>> #define DBL_DIG 15
>> #v-
>> (cytat z float.h). Czyli każda liczba o mniej niż 15 cyfrach po przecinku
>> jest w double reprezentowana DOKŁADNIE.
> 
> Bzdura. Znaczy to tylko tyle, że dla każdej takiej liczby istnieje
> taka wartość typu double, która zaokrąglona do 15 cyfr dziesiętnych
> da tę liczbę z powrotem.

Eee ? Chyba czas zacząć zadawać pytania wykładowcy od analizy numerycznej :>
 
-- 
    [ http://www.stringi.com/viper/ ] 
  All good things come to those who wait
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads