Discussion:
Błędny epsilon - this is not a bug, this is ?
(Wiadomość utworzona zbyt dawno temu. Odpowiedź niemożliwa.)
slawek
2012-11-01 10:15:13 UTC
Permalink
Tzw. maszynowy epsilon (see Wikipedia) wynosi nie więcej niż 1.111E-016 dla
liczb 64-bitowych. Taki wynik łatwo otrzymać nawet naiwnym algorytmem, w
którym po kolei sprawdzane są w pętli kolejne wartości epsilon - każda
kolejna nieco (o ułamek procenta) mniejsza od poprzedniej. Algorytm "fast"
adaptacyjnie zmienia krok itd. - nie ma to znacznego wypływu na wynik, ale
liczba kroków jest znacznie mniejsza.

Jednak zaglądając do float.h w MS VS C++ można znaleźć definicję
DBL_EPSILON, wraz ze stosownym komentarzem, 2.22044604925031310000E-016.
Jest to niemal 2 razy więcej, niż naprawdę wynosi epsilon (obliczony właśnie
programem skompilowanym w MSVS C++). "This is not a bug, this is
inaccuracy" - chciałoby się powiedzieć.

Zaglądamy dalej - Matlab - tak ostatnio chwalony - ma wbudowaną funkcję
eps - zgadnijcie co zwraca eps jako wynik liczbowy? Tak, też się zdziwiłem -
przecież Matlab to Matlab.

Jeszcze raz rzut oka do Wikipedii - jest sobie wyraźnie dobra wartość
epsilona dla double w tabelce - ale już np. program w Phytonie i wyniki z
niego - znowu błędne 2.22E-16 . I nie jest to "wina Phytona" - ale po prostu
błąd w programie.

"Phytonowcy", staff MS i ludzie z MathWorks popełnili jeden i ten sam błąd -
dzielili przez dwa. Ciąg wartości x[n], jakie otrzymywali, dla dostatecznie
dużego n nie spełniał nierówności 1.0+x[n] > 1.0. Nie jest źle... jeżeli
pamięta się, że dokładność tak wyznaczonego epsilona wynosi plus minus 50%.
To nawet w większości praktycznych zastosowań wystarcza. Ale nie jest dobrym
pomysłem, by tak niedokładną wartość wrzucać jako wzorcową do float.h - bo
99.8% ludzi będzie w ciemno ufało w nieomylność MS - zwłaszcza, że podane
jest to jako, cyt.:

#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that
1.0+DBL_EPSILON != 1.0 */

a to sugeruje poprawność wszystkich zapisanych cyfr znaczących. Tymczasem
eps znaleziony przez wykonywanie obliczeń (można oszacować epsilon przez
zapisane 1.0 oraz 1.0+epsilon bit po bicie mantysa i wykładnik - vide
IEEE753) leży gdzieś pomiędzy podanymi zakresami:

naive (no. of steps=36736783):
eps > 1.11022213668763790000E-016
eps <= 1.11022324691088480000E-016

fast (no. of steps=187):
eps > 1.11022302462515650000E-016
eps <= 1.11022302462515680000E-016


slawek
kenobi
2012-11-01 11:08:13 UTC
Permalink
Post by slawek
Tzw. maszynowy epsilon (see Wikipedia) wynosi nie więcej niż 1.111E-016 dla
liczb 64-bitowych. Taki wynik łatwo otrzymać nawet naiwnym algorytmem, w
którym po kolei sprawdzane są w pętli kolejne wartości epsilon - każda
kolejna nieco (o ułamek procenta) mniejsza od poprzedniej. Algorytm "fast"
adaptacyjnie zmienia krok itd. - nie ma to znacznego wypływu na wynik, ale
liczba kroków jest znacznie mniejsza.
Jednak zaglądając do float.h w MS VS C++ można znaleźć definicję
DBL_EPSILON, wraz ze stosownym komentarzem, 2.22044604925031310000E-016.
Jest to niemal 2 razy więcej, niż naprawdę wynosi epsilon (obliczony właśnie
programem skompilowanym w MSVS C++). "This is not a bug, this is
inaccuracy" - chciałoby się powiedzieć.
Zaglądamy dalej - Matlab - tak ostatnio chwalony - ma wbudowaną funkcję
eps - zgadnijcie co zwraca eps jako wynik liczbowy? Tak, też się zdziwiłem -
przecież Matlab to Matlab.
Jeszcze raz rzut oka do Wikipedii - jest sobie wyraźnie dobra wartość
epsilona dla double w tabelce - ale już np. program w Phytonie i wyniki z
niego - znowu błędne 2.22E-16 . I nie jest to "wina Phytona" - ale po prostu
błąd w programie.
"Phytonowcy", staff MS i ludzie z MathWorks popełnili jeden i ten sam błąd -
dzielili przez dwa. Ciąg wartości x[n], jakie otrzymywali, dla dostatecznie
dużego n nie spełniał nierówności 1.0+x[n] > 1.0. Nie jest źle... jeżeli
pamięta się, że dokładność tak wyznaczonego epsilona wynosi plus minus 50%.
To nawet w większości praktycznych zastosowań wystarcza. Ale nie jest dobrym
pomysłem, by tak niedokładną wartość wrzucać jako wzorcową do float.h - bo
99.8% ludzi będzie w ciemno ufało w nieomylność MS - zwłaszcza, że podane
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that
1.0+DBL_EPSILON != 1.0 */
a to sugeruje poprawność wszystkich zapisanych cyfr znaczących. Tymczasem
eps znaleziony przez wykonywanie obliczeń (można oszacować epsilon przez
zapisane 1.0 oraz 1.0+epsilon bit po bicie mantysa i wykładnik - vide
eps > 1.11022213668763790000E-016
eps <= 1.11022324691088480000E-016
eps > 1.11022302462515650000E-016
eps <= 1.11022302462515680000E-016
Ciekawe, ale dlaczego to jest dokladnie podwojona
wartosc epsilona? Z poczatku wydawalo mni sie ze slowo double odnosi sie wlasnie do tego (a nie do typu double) i ze ta podwojna wartosc ma jakiej uzasadnienie
slawek
2012-11-01 12:38:50 UTC
Permalink
Użytkownik "kenobi" napisał w wiadomości grup
Post by kenobi
Ciekawe, ale dlaczego to jest dokladnie podwojona
wartosc epsilona? Z poczatku wydawalo mni sie ze slowo double odnosi sie
wlasnie do tego (a nie do typu double) i ze ta podwojna wartosc ma jakiej
uzasadnienie
Jeżeli zapisać:

double x = 1.0;
while(1.0 + x > 1.0)
{
cout << (x * k) << endl; // gdzie 0.0 <= k && k < 1.0
}

to ostatnia liczba jaka się pojawia na ekranie jest mniejsza niż epsilon, a
przedostatnia jest większa niż epsilon.

Biorąc k = 0.5, czyli połowiąc - dostaniemy jako tę większą właśnie to co
wpisane jest we float.h i co zwraca Matlabowe eps.

Jednak - jak łatwo się przekonać, biorąc np. k = 0.9999, nie jest prawdą że
DBL_EPSILON z float.h jest naprawdę epsilonem w sensie definicji jaka jest w
komentarzu z float.h.

Po prostu ktoś gdzieś (i to przynajmniej 3 różnych ludzi, w zupełnie różnych
"firmach" - bo ci od Phytona to "sweterki") użył zbyt prostego algorytmu nie
zastanawiając się nad dokładnością, precyzją i takimi tam. Wyszło jak
wyszło - czyli z błędem około 50% (błąd względny w procentach wynosi około
(1-k)*100%). Jak policzyć 2.2E-16 +- 50% to wychodzi gdzieś od 1.1E-16 do
3.3E-16, czyli wszystko się zgadza. Ale bez sensu było wpisywanie w
DBL_EPSILON wszystkich cyferek - przy 50% dokładności to jedna cyfra znacząc
jest i tak za dużo.

Napisałem do MS - może poprawią (a może poprawili, nie chce mi się
instalować MSVS 2012, ale chyba zrobię to w najbliższej przyszłości - czytaj
za jakieś parę tygodni).

Do Matlab'owców - też a zwłaszcza - ale musiałbym jeszcze sprawdzić z
nowszym Matlab'em (zły eps jest z R2010b).

No i poprawić wpis w Wikipedii - fragment Phyton'owy.

Warto sprawdzić byłoby i z Octave/Scilab/.../GCC. Zajrzeć do normy IEEE (tam
powinno być dobrze, a może też sztucznie stworzyć eps przez rozrysowanie
bitów).

slawek
bartekltg
2012-11-01 13:53:27 UTC
Permalink
Post by slawek
Do Matlab'owców - też a zwłaszcza - ale musiałbym jeszcze sprawdzić z
nowszym Matlab'em (zły eps jest z R2010b).
W matalbie jest poprawnie.
"
eps Spacing of floating point numbers.
D = eps(X), is the positive distance from ABS(X) to the next larger in
magnitude floating point number of the same precision as X.
"

I działa zgodnie z tą definicją.
eps(1) = 2.2204e-016

we float.h dali ciała z definicją/warunkami zaokrąglania.

Więcej pod postem fira.

pzdr
bartekltg
slawek
2012-11-01 15:39:09 UTC
Permalink
Użytkownik "bartekltg" napisał w wiadomości grup
Post by bartekltg
we float.h dali ciała z definicją/warunkami zaokrąglania.
Bartuś, gratuluję ci pewności siebie. Przyda ci się ona przy wyjaśnianiu
dlaczego twórcy procesorów dodają liczby z większą "rozdziałką" niż one są
zapisywane.

Owszem, opis we float.h jest niezbyt udany (m.i. dlatego, że w określeniu
"najmniejszą liczbą x która 1 + x != 1" zapomniano o liczbach ujemnych).

Nadal jednak masz problem - twierdzisz coś zupełnie innego niż Wikipedia -
więc może sprostujesz wpis ibidem? Przy okazji doprowadzając hasło do
porządku: ta sama Wikipedia podaje jako wartość epsilon - w tym samym
tekście - raz jako 1.1E-16 a raz jako 2.2E-16. Jako w miarę inteligentny
człowiek rozumiesz, że niezależnie od tego ile naprawdę wynosi epsilon
(nawet jeżeli jest to okrągłe 42) - to przynajmniej jedną z tych wartości
należy wykluczyć. (Nie, nie twierdzę że Wikipedia jest nieomylna - ale że
skoro potrafisz, to powinieneś sprostować błędy w Wikipiedii, nie będę
zabraniał.)

Co do Matlaba - jeżeli jest inna definicja - to eps z Matlaba jest ok - w
sensie zgodności z definicją. Niemniej jednak błędem jest w takim razie
odrzucanie liczb mniejszych niż eps (tj. niż wartość jaką zwraca funkcja eps
z Matlaba), bo te liczby jednak zmieniają (i powinny zmieniać) wynik. Taki
przykładzik, w którym f jest taka że dla każdego n funkcja f(n+1) < f(n)
oraz f(n) > 0 :

m = 1; while( f(m) >= eps ) m++; /* m = 10*m + 100; */ s = 0.; for (k =
m; k > 0; k--) s += f(m);

Jeżeli użyjesz definicji i wartości eps z Matlab, to możesz - przez
przypadek - otrzymać inny wynik, niż kiedy usuniesz komentarz. Jeżeli
użyjesz definicji MS (i oczywiście o połowę mniejszego eps) - to niezależnie
od tego, czy usuniesz komentarz, czy go zostawisz - będziesz miał ten sam
wynik.

Wniosek jest oczywisty - podana przez ciebie definicja może w określonych
sytuacjach prowadzić do błędnych wyników. Definicja MS jest bardziej
bezpieczna.
bartekltg
2012-11-01 15:54:26 UTC
Permalink
Post by slawek
Użytkownik "bartekltg" napisał w wiadomości grup
Post by bartekltg
we float.h dali ciała z definicją/warunkami zaokrąglania.
Bartuś, gratuluję ci pewności siebie. Przyda ci się ona przy wyjaśnianiu
dlaczego twórcy procesorów dodają liczby z większą "rozdziałką" niż one
są zapisywane.
Kurde, 'sławuś', wuemy, zę masz problemy z czytaniem ze zrozumieniem,
ale się skup i przeczytaj te posty.
Post by slawek
Nadal jednak masz problem - twierdzisz coś zupełnie innego niż Wikipedia
- więc może sprostujesz wpis ibidem? Przy okazji doprowadzając hasło do
Gdzie twierdzę coś innego niż wykipedia?

Rozumiesz wynik tego:
Odpalamy:
ee=1.11022324691088480000E-16
a=1+ee
roznica = a-1

Wychodzi:
ee =
1.1102e-016
a =
1.0000
roznica =
2.2204e-016

I co tu więcej komentować.
Post by slawek
Co do Matlaba - jeżeli jest inna definicja - to eps z Matlaba jest ok -
w sensie zgodności z definicją. Niemniej jednak błędem jest w takim
razie odrzucanie liczb mniejszych niż eps (tj. niż wartość jaką zwraca
Błędem jest w ogóle działanie na takich zakresach.
To chyba podstawy 'numerków'.
Post by slawek
funkcja eps z Matlaba), bo te liczby jednak zmieniają (i powinny
zmieniać) wynik. Taki przykładzik, w którym f jest taka że dla każdego n
m = 1; while( f(m) >= eps ) m++; /* m = 10*m + 100; */ s = 0.; for (k
= m; k > 0; k--) s += f(m);
Jeżeli użyjesz definicji i wartości eps z Matlab, to możesz - przez
przypadek - otrzymać inny wynik, niż kiedy usuniesz komentarz. Jeżeli
użyjesz definicji MS (i oczywiście o połowę mniejszego eps) - to
niezależnie od tego, czy usuniesz komentarz, czy go zostawisz - będziesz
miał ten sam wynik.
Będziesz miał syf. To nie sa integery, nie powinno się działać
na 'ostatnich bitach'.

Za ten kod powyżęj to powinni walić linijką po łapach.
Post by slawek
Wniosek jest oczywisty - podana przez ciebie definicja może w
określonych sytuacjach prowadzić do błędnych wyników. Definicja MS jest
bardziej bezpieczna.
Twoje pomysły na korzystanie z epsylona sa niebezpieczne.

pzdr
bardtekltg
slawek
2012-11-01 16:45:29 UTC
Permalink
Użytkownik "bartekltg" napisał w wiadomości grup
Post by bartekltg
Gdzie twierdzę coś innego niż wykipedia?
Zajrzyj do Wikipedii, przeczytaj. Umiesz czytać - więc w czym trudność?
Post by bartekltg
Błędem jest w ogóle działanie na takich zakresach.
To chyba podstawy 'numerków'.
Stała Plancka ci zniknęła. Zniknęła ci stała Plancka do kwadratu podzielona
przez czwartą potęgą prędkości światła i pomnożona przez liczbę Avogadro.
Oczywiście... w CGS.
Post by bartekltg
Będziesz miał syf. To nie sa integery, nie powinno się działać
na 'ostatnich bitach'.
Nie będę miał. Nie znam twoje siostry. Te zdania mają tyle ze sobą
wspólnego, co podany przykład z liczbami integer.

W podanym przykładzie liczenie jest "po wszystkich bitach" - bez
"zapominania" o dodawaniu wyrazów, które choć dość małe, to jednak wynik
zmieniają. Dla ciebie może to być bez znaczenia - ot, nauczyli cię że np.
sinus alfa to prawie to samo co alfa (dobrze jeżeli jeszcze zapamiętałeś, że
alfa ma być w radianach). W takim obrazie rzeczywistości (np. gry
komputerowe) epsilon jest do niczego nie potrzebny: jak coś będzie nieco
krzywo i niezbyt dokładnie, to i tak framerate ważniejsze jest.
Post by bartekltg
Za ten kod powyżęj to powinni walić linijką po łapach.
Jakieś doświadczenia z dzieciństwa?

Ale ja nie o tym. Tylko z uprzejmym pytaniem: jak TY
(o-wielki-i-wspaniały-Bartusiu) rozwiązałbyś prosty problem... masz szereg,
możesz sumować dowolną (acz skończoną) ilość wyrazów tegoż. Każdy wyraz
szeregu jest nieco mniejszy co do modułu od poprzedniego. Oczywiście, szereg
jest zbieżny. Chcesz szybko ocenić ile wyrazów trzeba będzie uwzględnić w
obliczeniach, tak aby zminimalizować błędy zaokrągleń. Wiesz - za długo
pisać "dlaczego" - że suma pominiętych wyrazów (tj. tzw. reszta) jest
mniejsza niż ostatni nie-pominięty składnik. Nie chcesz robić tego przy
sumowaniu "od 1 do m", bo wiesz że wtedy błędy zaokrągleń będą zbyt duże (a
przecież wiesz co to schemat Hornera). Gorzej - każdy z wyrazów zawiera
czynnik C[n], który jest "bardzo trudny do obliczenia" (np. całka w
przestrzeni 5-cio wymiarowej), ale szczęśliwie wiesz, że Abs[C[n]] < 1
niezależnie od n.

I teraz totalnie głupie pytanie: przyda się jakiś epsilon do tego? Jaki,
jak, bo? Podaj jakieś konstruktywne rozwiązanie - przyda się!

Bo to co na razie robisz, to wygląda na typową trollerkę o to kto był
najbardziej bity linijką po łapach. (W tym niestety przegrywam - nikt nie
chce mnie w moim przedszkolu bić linijką - może to się zmieni, gdy zacznę
chodzić do podstawówki w mieście w którym dorastałeś - gdzie to było?)

Na serio poczytaj co pisze w Wikipedii:
http://en.wikipedia.org/wiki/Machine_epsilon - tabelka z niby IEEE-754 - jak
wół stoi 1.11e-16 i nawet obok pow(2,-53) jest
bartekltg
2012-11-01 16:50:36 UTC
Permalink
Post by slawek
Użytkownik "bartekltg" napisał w wiadomości grup
Post by bartekltg
Będziesz miał syf. To nie sa integery, nie powinno się działać
na 'ostatnich bitach'.
Nie będę miał. Nie znam twoje siostry.
Twoje ogólne dyletanctwo można tolerować. To, że mimo
usilnych prób nie byłeś w stanie przez tydzień pojąć
działania kwadratur numerycznych czy FFT mogę zrozumieć.
To, że nie rozumies,z jak używać liczb zmiennoprzecinkowych,
też. Nie każdy musi.
Ale chamstwa tolerować nie będę.

plonk
slawek
2012-11-01 17:18:51 UTC
Permalink
Użytkownik "bartekltg" napisał w wiadomości grup
Post by bartekltg
To, że nie rozumies,z jak używać liczb zmiennoprzecinkowych,
też. Nie każdy musi.
Sam jesteś tego najlepszym przykładem: gdy zapytać się ciebie o konkret i
poprosić o konstruktywne wyjaśnienie - udajesz obrażoną pensjonarkę. Swoją
drogą, jakoś tak nie widziałem (ale pewnie nie pamiętam lub nie zauważyłem)
abyś kiedykolwiek podał jakiś sensowny sposób rozwiązania jakiegokolwiek
problemu. Dobry jesteś tylko w FUD i PR, reszta to jakaś taka mglista.
Post by bartekltg
Ale chamstwa tolerować nie będę.
Źle cię oceniłem - myślałem "weźmie się Bartuś ujmie ambicją i honorem... i
hasło w Wikipedii poprawi... będzie pożytek dla Ludzkości". Ale widzę że
ambicji bardzo dużo, wiedzy trochę mało, pracowitości nic a nic, co do
honoru... nawet nie ma o czym pisać.

Teraz widzę że już pożytku z pana hrabiego (galicyjskiego) nie będzie.
kenobi
2012-11-01 17:58:01 UTC
Permalink
Post by slawek
Użytkownik "bartekltg" napisał w wiadomości grup
Post by bartekltg
To, że nie rozumies,z jak używać liczb zmiennoprzecinkowych,
też. Nie każdy musi.
Sam jesteś tego najlepszym przykładem: gdy zapytać się ciebie o konkret i
poprosić o konstruktywne wyjaśnienie - udajesz obrażoną pensjonarkę. Swoją
drogą, jakoś tak nie widziałem (ale pewnie nie pamiętam lub nie zauważyłem)
abyś kiedykolwiek podał jakiś sensowny sposób rozwiązania jakiegokolwiek
problemu. Dobry jesteś tylko w FUD i PR, reszta to jakaś taka mglista.
Post by bartekltg
Ale chamstwa tolerować nie będę.
Źle cię oceniłem - myślałem "weźmie się Bartuś ujmie ambicją i honorem... i
hasło w Wikipedii poprawi... będzie pożytek dla Ludzkości". Ale widzę że
ambicji bardzo dużo, wiedzy trochę mało, pracowitości nic a nic, co do
honoru... nawet nie ma o czym pisać.
Teraz widzę że już pożytku z pana hrabiego (galicyjskiego) nie będzie.
hehe, nie ma sie co tak spinać (choć kawałek
"(o-wielki-i-wspaniały-Bartusiu)" był całkiem niezły)

To co wy tu piszcie nie podchodzi mz
pod trolowanie, ja za bucerkę/dresiarstwo
uważam tzw dresiarskie (zupenie niemerytoryczne) dowalactwo.

Z tym epsilonem to ciekawa sprawa, faktycznie
mz moze być użyteczne i dobrze ze jest
zdefiniowane i dobrze też sie troche na tym
znac i przemyslec te sprawy, sam jednak
nie moge sie teraz zbytnio nad tym zastanowic
bo jetsem cholernie zmeczony i obolały
pozatym psuje mi sie maszyna (ale bedzie
trzeba wrocic do tego bo ta badz co badz
fundamenty)
kenobi
2012-11-01 18:09:56 UTC
Permalink
ale tak wogole, oczywista kwestia, czy tego epsilona nie 'zna' sie norrmalnie tj po prostu
jako 1 podzielic przez 2 do potegi 52 czy cos
w tym stylu - choc fpu to z tego co wiem to
wogole troche skomplikowana sprawa bo sa
rozne konfigurowalne stany 9np precyzja)

eogole z tego co kojarze to kompilatory
zdaje sie byc moze bez problmu obslugują
tzw typ long double

long double x = 1.0;

(wieadomo 80 bit) mimo ze sie tego w kodach rzadko uzywa mozliwe ze wiekszosc kompilatorow to po prostu normalnie obslugują

ktos wie jak to z tym jest?
slawek
2012-11-01 18:52:04 UTC
Permalink
Użytkownik "kenobi" napisał w wiadomości grup
Post by kenobi
To co wy tu piszcie nie podchodzi mz
pod trolowanie, ja za bucerkę/dresiarstwo
uważam tzw dresiarskie (zupenie niemerytoryczne) dowalactwo.
Nie lubię dryfów w kierunku przemocy (nie bawi mnie BDSM, nie bawi mnie
"bicie linijką po łapach" itd.), nie lubię dryfów nt. "syf" (syfilis jest
względnie łatwo wyleczalny, no i - jak każda choroba - nie ma w sobie nic
śmiesznego), nie wymyślam od "chamów" (znając przypadkiem Kodeks Boziewicza
i mając przodków... takich jakich miałem), staram się być w miarę rzeczowy i
pomocny. Nie używam też takich słów jak, wyjątkowo zacytuję, "kurde".

Nawet zdziwię cię może - argumentacja Bartka nt. epsilona (tj. ściśle
merytoryczna jej część) moim zdaniem zasługuje na to, aby poprawić hasło w
Wikipedii i paru innych źródłach. W tym w Numerical Recipes, Teukolskyego et
al. (tak, w nowym wydaniu - co można sprawdzić online - jest definicja
epsilona jako "The smallest (in magnitude) number... produces result
different from 1.0" ) - co łatwo można sprawdzić on-line (strona 10., sekcja
1.1.2.). www.nr.com

O ile oczywiście Teukolsky i współautorzy podzielą opinię Bartka.
Post by kenobi
Z tym epsilonem to ciekawa sprawa, faktycznie
mz moze być użyteczne i dobrze ze jest
zdefiniowane i dobrze też sie troche na tym
Zaczynając wątek napisałem, że nie ma wielkiego sensu pisać "wszystkich cyfr
epsilona" - raczej rząd wielkości jest istotny. Niemniej jednak jest pewne
niechlujstwo w tym co jest we float.h do MS Visual Studio - definicja nie
wytrzymuje ujemnych liczb, wynik nie odpowiada temu czym ma być według
definicji.
Post by kenobi
znac i przemyslec te sprawy, sam jednak
nie moge sie teraz zbytnio nad tym zastanowic
bo jetsem cholernie zmeczony i obolały
Bywa. Nie ma jednak co się zbyt skupiać nad "problemem z epsilonem" - są
ważniejsze sprawy. Może po prostu najważniejsza nauka z tego jest, aby
zamiast magicznych stałych zapisanych przez #define - zawsze wszystko
wyliczać samemu? Potrzebujemy takiego najmniejszego eps > 0, że 1.0 + eps >
1.0 ? To policzmy go sobie - a nie ufajmy, że w jakimś pliku float.h czy
podobnym będzie dobra wartość. Choćby dlatego, że kiedyś program może być
uruchamiany na jakiejś innej maszynie, w innej konfiguracji, z zupełnie inną
architekturą.
kenobi
2012-11-01 19:26:32 UTC
Permalink
Post by slawek
Użytkownik "kenobi" napisał w wiadomości grup
Post by kenobi
To co wy tu piszcie nie podchodzi mz
pod trolowanie, ja za bucerkę/dresiarstwo
uważam tzw dresiarskie (zupenie niemerytoryczne) dowalactwo.
Nie lubię dryfów w kierunku przemocy (nie bawi mnie BDSM, nie bawi mnie
"bicie linijką po łapach" itd.), nie lubię dryfów nt. "syf" (syfilis jest
względnie łatwo wyleczalny, no i - jak każda choroba - nie ma w sobie nic
śmiesznego), nie wymyślam od "chamów" (znając przypadkiem Kodeks Boziewicza
i mając przodków... takich jakich miałem), staram się być w miarę rzeczowy i
pomocny. Nie używam też takich słów jak, wyjątkowo zacytuję, "kurde".
Nawet zdziwię cię może - argumentacja Bartka nt. epsilona (tj. ściśle
merytoryczna jej część) moim zdaniem zasługuje na to, aby poprawić hasło w
Wikipedii i paru innych źródłach. W tym w Numerical Recipes, Teukolskyego et
al. (tak, w nowym wydaniu - co można sprawdzić online - jest definicja
epsilona jako "The smallest (in magnitude) number... produces result
different from 1.0" ) - co łatwo można sprawdzić on-line (strona 10., sekcja
1.1.2.). www.nr.com
O ile oczywiście Teukolsky i współautorzy podzielą opinię Bartka.
Post by kenobi
Z tym epsilonem to ciekawa sprawa, faktycznie
mz moze być użyteczne i dobrze ze jest
zdefiniowane i dobrze też sie troche na tym
Zaczynając wątek napisałem, że nie ma wielkiego sensu pisać "wszystkich cyfr
epsilona" - raczej rząd wielkości jest istotny. Niemniej jednak jest pewne
niechlujstwo w tym co jest we float.h do MS Visual Studio - definicja nie
wytrzymuje ujemnych liczb, wynik nie odpowiada temu czym ma być według
definicji.
Post by kenobi
znac i przemyslec te sprawy, sam jednak
nie moge sie teraz zbytnio nad tym zastanowic
bo jetsem cholernie zmeczony i obolały
Bywa. Nie ma jednak co się zbyt skupiać nad "problemem z epsilonem" - są
ważniejsze sprawy. Może po prostu najważniejsza nauka z tego jest, aby
zamiast magicznych stałych zapisanych przez #define - zawsze wszystko
wyliczać samemu? Potrzebujemy takiego najmniejszego eps > 0, że 1.0 + eps >
1.0 ? To policzmy go sobie - a nie ufajmy, że w jakimś pliku float.h czy
podobnym będzie dobra wartość. Choćby dlatego, że kiedyś program może być
uruchamiany na jakiejś innej maszynie, w innej konfiguracji, z zupełnie inną
architekturą.
nie czytalem chasla w wiki i nie bardzop che
mi sie tez sledzic kto co tu powiedzial, juz
lepiej sie zastanowic nad samym tym epsilonem

czy ten epsilon (2.2? 1.1?) to jest moze po prostu 'roznica' miedzy kolejnymi doublemi
czy to jest pól tej róznicy czy co? Ile wynosi
róznica miedzy doublami w epsilonach? ta roznica jest chyba stała, czy tez wchodza tu jakies komplikacje powodujace ze licZyc sie moze cos innego niz ziarnistosc double? (mozliwe ze to juz jest tu napisane ale nie mialem sily sie wglebiac)
slawek
2012-11-01 20:24:13 UTC
Permalink
Użytkownik "kenobi" napisał w wiadomości grup
Post by kenobi
czy ten epsilon (2.2? 1.1?) to jest moze po prostu 'roznica' miedzy kolejnymi doublemi
czy to jest pól tej róznicy czy co? Ile wynosi
Celna uwaga.

Ja "od zawsze" jakoś tak byłem przyzwyczajony (epsilonowo-deltowa definicja
granicy funkcji), że epsilon to "coś małego", takie że owszem nie jest to
zero, ale w istocie rzeczy jest to najmniejsza wartość jaka da się użyć w
obliczeniach. Kwestia jak zapisane są liczby (dwójkowo, trójkowo, czy może
analogowo np. napięcie elektryczne) - to zupełnie inny problem. Czyli
definicja sup { epsilon in R : 1+epsilon > 1 } wydaje mi się zupełnie
naturalna i zrozumiała nawet dla 10-latka. Oraz najbardziej przydatna - nie
interesuje mnie, co za krasnale siedzą w CPU/FPU/APU - byle liczyły "jak
trzeba".

Oczywiście dla hodowców krasnali - tj. dla konstruktorów procesorów itd. -
epsilon może być równy matematycznie pojętej różnicy pomiędzy liczbą 1
zapisaną w (no w czym, FPU czy RAM?)... a najmniej różną od niej liczbą
nieco większą. "Matematycznie pojętą" oznacza, że nie musi być tak, ze da
się policzyć (1+epsilon) - 1 na danej maszynce (tj. w FPU) - ale, że
teoretycznie tyle.

Tyle że w float.h jest wprost napisany warunek 1.0 + x != 1.0 .

Niechlujstwo jest w tym, że jak damy x = -10.0, to wychodzi 1.0 + (-10.0)
czyli w przybliżeniu -9.0. A w przybliżeniu dlatego, że FPU trochę
zaokrągli. W każdym razie warunek z definicji będzie spełniony. Ale
oczywiście to jest czepialstwo, bo "wiadomo o co chodzi". Że ma być x > 0.
czyli dodatnie.

Mniej oczywistym błędem jest to, że liczba double x = 1.111E-16 też daje 1.0
+ x != 1.0, czyli spełnia warunek. Natomiast MS uważa że epsilon > 2.22E-16
.

I możemy się spierać, jak zdefiniować epsilon - ale po prostu to co jest we
float.h jest wewnętrznie sprzeczne.


A teraz wiki - w tym samym haśle jest jednocześnie, że epsilon jest równe
1.11E-16 i że jest równe 2.22E-16. Nieważne jak definiujemy epsilon - ale
ponieważ 1.11E-16 != 2.22E-16 (w sensie matematycznym i w sensie FPU też) -
to znaczy, że w Wikipedii (EN) jest pomyłka. Albo w jednym miejscu, albo w
drugim, albo w obu. To logiczne (jak mawiał Spock).


Jeszcze o roli epsilona. Gdy służy do np. wyboru kroku jako sqrt(epsilon),
to nie ma wielkiego znaczenia, czy jest 1.11E-16 czy 2.22E-16.

Problemy mogą być, gdy np. uznamy że wolno zaokrąglać wartości mniejsze niż
epsilon zapisując je jako konkretnie zero. Albo gdy mniejsze od epsilon*coś.
Tego typu praktyki były w obliczeniach w Mathematica'e swego czasu - jak
część Im(z) < epsilon*coś to uznawało, że liczba jest czysto rzeczywista.


Przy "dobrym epsilon" zaokrąglenie w zero jest sensowne. Przy złym - będą
błędy. Jak duże? A to już zależy od szczegółów. Podobnie jak to było z
"Pentium bug".
slawek
2012-11-01 20:30:24 UTC
Permalink
Użytkownik "slawek" napisał w wiadomości grup
dyskusyjnych:5092da70$0$1225$***@news.neostrada.pl...

definicja epsilon = inf { x in R : 1 + x > 1 } === sup { x in R : 1 + x
== 0 }
slawek
2012-11-01 22:23:21 UTC
Permalink
Użytkownik "slawek" napisał w wiadomości grup
dyskusyjnych:5092da70$0$1225$***@news.neostrada.pl...

definicja epsilon = inf { x in R : 1 + x > 1 } === sup { x in R : 1 + x
== 1 }
Adam Wysocki
2012-11-05 07:26:55 UTC
Permalink
Post by kenobi
nie czytalem chasla w wiki i nie bardzop che
Czy ty się kiedyś ośle nauczysz wycinać cytaty? Czy przerasta to twoje
zdolności intelektualne?
Post by kenobi
róznica miedzy doublami w epsilonach? ta roznica jest chyba stała, czy tez wchodza tu jakies komplikacje powodujace ze licZyc sie moze cos innego niz ziarnistosc double? (mozliwe ze to juz jest tu napisane ale nie mialem sily sie wglebiac)
Wycinać cytaty i zawijać wiersze.

http://evil.pl/pip/netykieta.html
http://informatyka.3bird.net/netykieta.html

Nie wracaj dopóki się nie douczysz zasad korzystania z Usenetu.
--
Gof
http://www.chmurka.net/
slawek
2012-11-05 12:04:18 UTC
Permalink
Post by Adam Wysocki
Czy ty się kiedyś ośle nauczysz wycinać cytaty? Czy przerasta to twoje
zdolności intelektualne?
Panie Adamie, zadam takie osobiste pytanie: czy kiedykolwiek nauczy się pan
zachowywać cywilizowany poziom dyskusji, czy też przekracza to pana
możliwości w sensie tzw. kompetencji miękkich?
Post by Adam Wysocki
Wycinać cytaty i zawijać wiersze.
Panie Adamie, czy mamy panu pomóc skonfigurować czytnik news'ów, czy jednak
potrafi sam pan to zrobić? Bo z pańskiej, dość panicznie brzmiącej (gdy
odczytać ją na głos), korespondencji wynika, iż niezawinięte wiersze są dla
pana źródłem niewyobrażalnej udręki. A jako ludzie dobrego serca chętnie
pomożemy.
Adam Wysocki
2012-11-06 10:43:48 UTC
Permalink
Nie do Ciebie piszę. Ty już pokazałeś w tym temacie swój poziom.
--
Gof
http://www.chmurka.net/
AK
2012-11-02 08:37:24 UTC
Permalink
Bywa. Nie ma jednak co się zbyt skupiać nad "problemem z epsilonem" - są ważniejsze sprawy. Może
po prostu najważniejsza nauka z tego jest, aby zamiast magicznych stałych zapisanych przez
#define - zawsze wszystko wyliczać samemu? Potrzebujemy takiego najmniejszego eps > 0, że 1.0 +
eps > 1.0 ? To policzmy go sobie - a nie ufajmy, że w jakimś pliku float.h czy podobnym będzie
dobra wartość.
POLICZMY !!?
Niby po co ?
Wystarczy miec orientacje o rzedzie "maszynowego" epsilona.
Potem go pomnozyc _przynajmniej_ prze 100 ;) i uzywac
w _normalnej_ (a nie skrajnej) numeryce.
Choćby dlatego, że kiedyś program może być uruchamiany na jakiejś
innej maszynie, w innej konfiguracji, z zupełnie inną architekturą.
No wlasnie. I co wtedy ?
Skad niby wiadomo, ze tam bedzie w ogole IEEE ?
Mowie to jako programista pracujacy jeszcze na Odrze.
Na tej Odrze podejscie przez ciebie prezentowane
byloby srogo ukarane (nie tylko niedzialaniem programow).
Jedynym z Was dwoch, ktory utrzymal by sie w "pracy" bylby
Bartek.
a nie ufajmy, że w jakimś pliku float.h czy podobnym będzie dobra wartość.
Tu sie zgadzam w 100%. Mozna pojsc nawet dalej.W ogole ich nie
uzywac/nie zwracac na nie uwagi.

Bo prawdziwy epsilon moj drogi zburaczaly "hrabio" (vide chamski
wtret do Bartka o siostrze - twoich przeprosin nie zauwazylem) _zawsze_
powinno sie dobierac w scislym zwiazku z natura problemu/algorytmu
numerycznego i z natury swej powinien on byc o wiele wyzszy
od precyzji maszynowej.

AK
slawek
2012-11-02 09:45:26 UTC
Permalink
Użytkownik "AK" napisał w wiadomości grup
Post by AK
Wystarczy miec orientacje o rzedzie "maszynowego" epsilona.
Potem go pomnozyc _przynajmniej_ prze 100 ;) i uzywac
w _normalnej_ (a nie skrajnej) numeryce.
Na poziomie gimbusa - tak, wystarczy.

Na poziomie "ekstremalnej numeryki" - nie masz.

Zgadnij czym się zajmują profesjonaliści.
Post by AK
Skad niby wiadomo, ze tam bedzie w ogole IEEE ?
Ze specyfikacji sprzętu? Z manuala? Ja tam się "nie znam" - ale co to jest
te IEEE/ISO/ANSI/PN ?
Post by AK
Mowie to jako programista pracujacy jeszcze na Odrze.
Na tej Odrze podejscie przez ciebie prezentowane
byloby srogo ukarane (nie tylko niedzialaniem programow).
Jedynym z Was dwoch, ktory utrzymal by sie w "pracy" bylby
Bartek.
Masz 100% racji - w komunistycznym systemie, na sprzęcie made in republika
ludowa - na którym nota bene np. wyliczano ile traktorów będzie produkować
Ursus w 2020 roku - Bartek dawałby sobie radę doskonale. Na twoje i Bartka
nieszczęście nie mamy już komunistycznego systemu. Jakby to określić...
system się zmienił. I nie chodzi o przesiadkę z George na Windows 8.

Oczywiście - jak baaardzo chcecie - to napiszcie sobie z Bartkiem emulator
Odry, a może i RIAD-a. Jak wam nie wystarcza pielęgnowanie wspomnień o
pierwszym gumiaku i atarynce z Peweksu. Ale wtedy wasze zdanie będziemy
cenić mniej więcej tak jak i inne eksponaty muzealne.
Post by AK
wtret do Bartka o siostrze - twoich przeprosin nie zauwazylem) _zawsze_
Bartek napisał o tym że mam cyt. "syf". To jest pomówienie. Ja napisałem w
odpowiedzi dwa prawdziwe zdania. Jedno: "nie mam syfilisu" . Drugie: "nie
znam twojej siostry". Domyślanie się związku przyczynowo-skutkowego przez
Bartka było nieuprawnionym rozumowaniem. Przepraszać nie mam za co. Owszem,
Bartek powinien przeprosić i powinien wiedzieć za co. Albo - jeszcze
lepiej - nie przepraszać i po prostu nie próbować używać wulgaryzmów, gróźb,
słów odnoszących się do przemocy fizycznej i ogólnie "mowy nienawiści".
Post by AK
powinno sie dobierac w scislym zwiazku z natura problemu/algorytmu
numerycznego i z natury swej powinien on byc o wiele wyzszy
od precyzji maszynowej.
Każdy powinien być piękny, młody i bogaty.

Rozumiesz pojęcia "postawa życzeniowa", "kompromis", "konieczność",
"ograniczenia", "budżet"? Jeżeli tak - to nie muszę więcej pisać. Jeżeli
nie - to nie ma sensu abym pisał.
Michoo
2012-11-02 21:05:14 UTC
Permalink
Użytkownik "AK" napisał w wiadomości grup
Post by AK
Skad niby wiadomo, ze tam bedzie w ogole IEEE ?
Ze specyfikacji sprzętu? Z manuala?
Jakbyś przed trollowaniem zadał sobie trud jego przeczytania to byś nie
znowu pieprzył jak potłuczony. Współczesny sprzęt operuje wewnętrznie na
liczbach 80 bitowych. [*]

Obliczenia są przycinane w momencie konwersji do double, dla pełnej
zgodności ze standardem niektóre kompilatory mają specyficzne opcje
powodujące to przycięcie po każdej operacji, w przeciwnym razie ciąg
obliczeń ma większą dokładność niż to wynika z wykonania kolejnych
obliczeń w typie double. "Eksperymentalnie" możesz więc otrzymywać
bzdury nie mające związku z formatem "double".


[*] Chodzi o to, żeby zapewnić dostateczną precyzję na "zwykłym" double.

Btw: Na porządnych kompilatorach masz pełną precyzję dostępną przez
"long double" o długości 12 bajtów.
--
Pozdrawiam
Michoo
slawek
2012-11-03 09:14:05 UTC
Permalink
Użytkownik "Michoo" napisał w wiadomości grup
Post by Michoo
Jakbyś przed trollowaniem zadał sobie trud jego przeczytania to byś nie
znowu pieprzył jak potłuczony. Współczesny sprzęt operuje wewnętrznie na
liczbach 80 bitowych. [Chodzi o to, żeby zapewnić dostateczną precyzję na
"zwykłym" double.]
I znowu "mowa nienawiści", próba manipulacji - zamiast merytorycznej wiedzy.

Choćby o tym, jak wygląda architektura procesorów Itanium.
Post by Michoo
Obliczenia są przycinane w momencie konwersji do double, dla pełnej
zgodności ze standardem niektóre kompilatory mają specyficzne opcje
Gdyby były obcinane, efektu nie byłoby. Kiepsko jak widzę z liczeniem na
palcach.

One są zaokrąglane - czyli także "w górę", ceil.

I nie dlatego aby uzyskać zgodność ze standardem (dla tej zgodności
obliczenia musiałyby być przeprowadzane na liczbach 64-bitowych, ewentualnie
po każdym pojedynczym działaniu arytmetycznym przekształcane na 64-bitowe,
co da się zrobić np. w gcc jest -ffloat-store). Ale z oczywistej przyczyny,
że nie da się zapisywać liczb 80-bitowych w 64 bitach bez utraty informacji.
Post by Michoo
powodujące to przycięcie po każdej operacji, w przeciwnym razie ciąg
Tym razem ja zachowam się nieładnie: przyciąć... to można palec szufladą.
Post by Michoo
obliczeń w typie double. "Eksperymentalnie" możesz więc otrzymywać bzdury
nie mające związku z formatem "double".
Podsumowując - polski "informatyk" jest głęboko wierzący: woli wierzyć w
swoje wewnętrzne głębokie przekonanie we własną nieomylność , niż zmierzyć
się z rzeczywistością i zauważyć chociażby tak prosty fakt, jak że 2.22E-16
nie równa się 1.11E-16.

Tak Michoo, mógłbyś być nawet papieżem i upierać się że Ziemia jest płaska,
albo że Ziemia stoi Słońce robi epicykle, albo że Ziemia jest w miejscu
spełniającym mocną zasadę kosmologiczną - ale to nie zmienia faktu "jednak
dodanie, używając liczb double, 1.5E-16 i 1.0 daje więcej niż 1.0".

A jednak się dodaje! ... Teraz czekam na stosik.

Niemniej szacun - dołączyłeś do całkiem pokaźnego stadka osobników, którym
żaden jakiś tam Eksperyment nie będzie będzie mówił co mają robić.
Michoo
2012-11-03 16:59:28 UTC
Permalink
Użytkownik "Michoo" napisał w wiadomości grup
Post by Michoo
Jakbyś przed trollowaniem zadał sobie trud jego przeczytania to byś
nie znowu pieprzył jak potłuczony. Współczesny sprzęt operuje
wewnętrznie na liczbach 80 bitowych. [Chodzi o to, żeby zapewnić
dostateczną precyzję na "zwykłym" double.]
I znowu "mowa nienawiści", próba manipulacji - zamiast merytorycznej wiedzy.
Ty trollujesz jak karmię trolle - to chyba standard.
Choćby o tym, jak wygląda architektura procesorów Itanium.
I zapomniałem już że czepiasz się "domyślnych" dla innych szczegółów.
Nie mówię o Itanium, nie mówię o NEONach, czy innych FVP. Jeżeli nie
wspomniano inaczej to mówimy na tej grupie o FPU x86.

No chyba, że Ty testowałeś na Itanium i nie raczyłeś o tym wspomnieć?
Post by Michoo
Obliczenia są przycinane w momencie konwersji do double, dla pełnej
zgodności ze standardem niektóre kompilatory mają specyficzne opcje
Gdyby były obcinane,
Nie obcinane. "Przycinane" - znaczy się redukowanie bez wdawania się w
szczegóły implementacji. (Tryb zaokrąglania można zresztą ustawić.)
One są zaokrąglane - czyli także "w górę", ceil.
Nie chce mi się sprawdzać, ale oidp jest to zaokrąglanie do
najbliższego. Zresztą tylko taka forma by miała sens przy tej dyskusji o
dokładności.
I nie dlatego aby uzyskać zgodność ze standardem (dla tej zgodności
obliczenia musiałyby być przeprowadzane na liczbach 64-bitowych,
Ale FPU nie liczy na 64 bitowych.
ewentualnie po każdym pojedynczym działaniu arytmetycznym przekształcane
na 64-bitowe, co da się zrobić np. w gcc jest -ffloat-store).
Tak, właśnie o tym napisałem.
Post by Michoo
powodujące to przycięcie po każdej operacji, w przeciwnym razie ciąg
Tym razem ja zachowam się nieładnie: przyciąć... to można palec szufladą.
Loglan jest równie ścisły co mało użyteczny.
Post by Michoo
obliczeń w typie double. "Eksperymentalnie" możesz więc otrzymywać
bzdury nie mające związku z formatem "double".
Podsumowując - polski "informatyk" jest głęboko wierzący: woli wierzyć w
swoje wewnętrzne głębokie przekonanie we własną nieomylność , niż
zmierzyć się z rzeczywistością i zauważyć chociażby tak prosty fakt, jak
że 2.22E-16 nie równa się 1.11E-16.
Gdzie ja się odnosiłem do tej wartości? Ja tylko napisałem ogólnie, że
liczenie bez uwzględnienia platformy może dawać dziwne wyniki. To Ty
wspomniałeś, że z manuala coś wynika, mimo, że go chyba nie czytałeś.
"jednak dodanie, używając liczb double, 1.5E-16 i 1.0 daje więcej
niż 1.0".
Tak. I jak Ci już wspomniano - w praktyce nie interesuje programisty
dokładność maszynowa a odległość między dwiema liczbami, czyli 2*e.
Komentarz jest błędny w nagłówku a dobry w matlabie.
Niemniej szacun - dołączyłeś do całkiem pokaźnego stadka osobników,
którym żaden jakiś tam Eksperyment nie będzie będzie mówił co mają robić.
Wydaje ci się.
--
Pozdrawiam
Michoo
slawek
2012-11-03 21:22:55 UTC
Permalink
Użytkownik "Michoo" napisał w wiadomości grup
I zapomniałem już że czepiasz się "domyślnych" dla innych szczegółów. Nie
mówię o Itanium, nie mówię o NEONach, czy innych FVP. Jeżeli nie wspomniano
inaczej to mówimy na tej grupie o FPU x86.
Podobno "zwykłe procesory" lepiej liczą instrukcjami SSE niż "normalnymi".
Sam się zdziwiłem.
Nie chce mi się sprawdzać, ale oidp jest to zaokrąglanie do najbliższego.
Zresztą tylko taka forma by miała sens przy tej dyskusji o dokładności.
Czyli jednak są zaokrąglane - a nie przycinane? Wiem, marudzę.
Tak. I jak Ci już wspomniano - w praktyce nie interesuje programisty
dokładność maszynowa a odległość między dwiema liczbami, czyli 2*e.
Komentarz jest błędny w nagłówku a dobry w matlabie.
Po drugie - czyli jednak mam rację - jest błąd w float.h ? Jest!

Po pierwsze - właśnie sam napisałeś, że to co jest równe 2.2E-16 to
odległość między dwiema liczbami i nie jest to epsilon. I znowu mam rację?!
Dziwne.

Po trzecie - zamiast napisać, cyt., "nie interesuje programisty" -
powinieneś napisać, iż ciebie nie interesuje. (Czyli po prostu nie uogólniać
swoich opinii jako opinii wszystkich programistów, bo są to - być może nawet
bardzo celne - ale wyłącznie twoje własne spostrzeżenia.)

Podsumowując - dobrze jeżeli jest już poprawka w Wikipedii - to pozytywny
rezultat dyskusji. A problem jest dużo bardziej poważny, niż mi się
wydawało - po prostu nie wiadomo ile bitów mantysy jest naprawdę użyte (tj.
czy będą użyte 64 bitowe liczby double, czy 80 bitowe rejestry FPU, zależy
od humoru kompilatora).
kenobi
2012-11-04 14:42:55 UTC
Permalink
Post by slawek
Użytkownik "Michoo" napisał w wiadomości grup
I zapomniałem już że czepiasz się "domyślnych" dla innych szczegółów. Nie
mówię o Itanium, nie mówię o NEONach, czy innych FVP. Jeżeli nie wspomniano
inaczej to mówimy na tej grupie o FPU x86.
Podobno "zwykłe procesory" lepiej liczą instrukcjami SSE niż "normalnymi".
Sam się zdziwiłem.
Nie chce mi się sprawdzać, ale oidp jest to zaokrąglanie do najbliższego.
Zresztą tylko taka forma by miała sens przy tej dyskusji o dokładności.
Czyli jednak są zaokrąglane - a nie przycinane? Wiem, marudzę.
Tak. I jak Ci już wspomniano - w praktyce nie interesuje programisty
dokładność maszynowa a odległość między dwiema liczbami, czyli 2*e.
Komentarz jest błędny w nagłówku a dobry w matlabie.
Po drugie - czyli jednak mam rację - jest błąd w float.h ? Jest!
Po pierwsze - właśnie sam napisałeś, że to co jest równe 2.2E-16 to
odległość między dwiema liczbami i nie jest to epsilon. I znowu mam rację?!
Dziwne.
Po trzecie - zamiast napisać, cyt., "nie interesuje programisty" -
powinieneś napisać, iż ciebie nie interesuje. (Czyli po prostu nie uogólniać
swoich opinii jako opinii wszystkich programistów, bo są to - być może nawet
bardzo celne - ale wyłącznie twoje własne spostrzeżenia.)
Podsumowując - dobrze jeżeli jest już poprawka w Wikipedii - to pozytywny
rezultat dyskusji. A problem jest dużo bardziej poważny, niż mi się
wydawało - po prostu nie wiadomo ile bitów mantysy jest naprawdę użyte (tj.
czy będą użyte 64 bitowe liczby double, czy 80 bitowe rejestry FPU, zależy
od humoru kompilatora).
korzysci z tej dyskusji sa bo wreszcie jakis ciekawy temat, 80 bitowe sa chyba nie tylko rejestry fpu, bo sa chyba polecenia umozliwiajace
zapis tego jako 10bajt do ram
Michoo
2012-11-05 10:07:52 UTC
Permalink
Użytkownik "Michoo" napisał w wiadomości grup
Post by Michoo
Nie chce mi się sprawdzać, ale oidp jest to zaokrąglanie do
najbliższego. Zresztą tylko taka forma by miała sens przy tej dyskusji
o dokładności.
Czyli jednak są zaokrąglane - a nie przycinane?
Są przycinane do 64 bitów afaik na 4 sposoby:
- down
- up
- near
- trunc

Domyślne jest near.

Wolę słowo "przycinane", niż zaokrąglane, bo inaczej mamy "zaokrąglanie
przez obcięcie bitów", a tak jest "przycięcie bitów (z zaokrągleniem)".
Wiem, marudzę.
Marudzisz, zwłaszcza, że najpierw błędnie napisałeś o zaokrąglaniu w górę.
Post by Michoo
Tak. I jak Ci już wspomniano - w praktyce nie interesuje programisty
dokładność maszynowa a odległość między dwiema liczbami, czyli 2*e.
Komentarz jest błędny w nagłówku a dobry w matlabie.
Po drugie - czyli jednak mam rację - jest błąd w float.h ? Jest!
Jest, ale wynika z czego innego niż myślisz.
Po pierwsze - właśnie sam napisałeś, że to co jest równe 2.2E-16 to
odległość między dwiema liczbami i nie jest to epsilon. I znowu mam
rację?! Dziwne.
Nie epsilon _maszynowy_ na FPU x86, które jak już wspomniano jest 80
bitowe. To, że dodanie ~połowy tej wartości wystarcza dla uzyskania
1.0+e!=1.0 wynika z tych 80 bitów i polityki near. W szerszym typie
wynik masz bliżej (1.0+2.2E-16) niż 1.0 więc jest zaokrąglane do
(1.0+2.2E-16) w momencie przycięcia do double. Jeżeli byś operował na
czystym double (64 bit) to zabraknie ci bitów na reprezentację tej sumy
i afaik nadal dostaniesz 1.0.

W związku z tym:
- 2.2E-16 nie jest najmniejszą wartością jaka na FPU x86 spowoduje
zajście nierówności. Jest najmniejszą taką wartością w typie double.
Po trzecie - zamiast napisać, cyt., "nie interesuje programisty" -
powinieneś napisać, iż ciebie nie interesuje. (Czyli po prostu nie
uogólniać swoich opinii jako opinii wszystkich programistów, bo są to -
być może nawet bardzo celne - ale wyłącznie twoje własne spostrzeżenia.)
float.h jest częścią standardu i odnosi się do standardowych typów
float(32 bit) i double (64 bit). Gdyby ten nagłówek oparto o corner-case
x86 to programista piszący np na VFP by się bardzo zdziwił, że ten
epsilon nie działa.

Na którymś z egzotycznych procesorów (niagara? alfa?) można było
ustawiać zaokrąglanie dla każdego rozkazu fpu. Wyobrażasz sobie, że w C
trzeba by przy każdej operacji float/double podawać prefix jak to
zaokrąglić?
Podsumowując - dobrze jeżeli jest już poprawka w Wikipedii - to
pozytywny rezultat dyskusji. A problem jest dużo bardziej poważny, niż
mi się wydawało - po prostu nie wiadomo ile bitów mantysy jest naprawdę
użyte (tj. czy będą użyte 64 bitowe liczby double, czy 80 bitowe
rejestry FPU, zależy od humoru kompilatora).
I zazwyczaj nie ma to znaczenia. Nikt nie robi poważnej numeryki
opierając się o to, że na x86 połowa epsilona double wystarcza.
--
Pozdrawiam
Michoo
slawek
2012-11-05 11:48:37 UTC
Permalink
Post by Michoo
Jest, ale wynika z czego innego niż myślisz.
Pożycz szklanej kuli - tej dzięki której wiesz co ja myślę. ;)
Post by Michoo
- 2.2E-16 nie jest najmniejszą wartością jaka na FPU x86 spowoduje zajście
nierówności. Jest najmniejszą taką wartością w typie double.
Typ double (tj. zmienne tego typu) sam z siebie się nie potrafią dodawać.
Post by Michoo
float.h jest częścią standardu i odnosi się do standardowych typów
Tj. o jakim standardzie piszesz?
Post by Michoo
ustawiać zaokrąglanie dla każdego rozkazu fpu. Wyobrażasz sobie, że w C
trzeba by przy każdej operacji float/double podawać prefix jak to
zaokrąglić?
Owszem. I to jest /nieco/ dziwaczne uczucie, że chyba tak się powinno robić.
Post by Michoo
I zazwyczaj nie ma to znaczenia. Nikt nie robi poważnej numeryki opierając
się o to, że na x86 połowa epsilona double wystarcza.
Wyznanie, że mało znasz ludzi robiących obliczenia numeryczne, a w
szczególności wśród tych osób nikogo takiego co przykłada jakiekolwiek
znaczenie do wartości epsilon?
Michoo
2012-11-05 12:10:38 UTC
Permalink
Post by slawek
Post by Michoo
Jest, ale wynika z czego innego niż myślisz.
Pożycz szklanej kuli - tej dzięki której wiesz co ja myślę. ;)
Post by Michoo
- 2.2E-16 nie jest najmniejszą wartością jaka na FPU x86 spowoduje
zajście nierówności. Jest najmniejszą taką wartością w typie double.
Typ double (tj. zmienne tego typu) sam z siebie się nie potrafią dodawać.
Ale można je dodać zgodnie ze standardem i niezgodnie ze standardem.
Post by slawek
Post by Michoo
float.h jest częścią standardu i odnosi się do standardowych typów
Tj. o jakim standardzie piszesz?
ISO/IEC 9899:TC3

Tu jest nawet napisane znacznie dobitniej co ma być w EPS_DOUBLE:

The values given in the following list shall be replaced by constant
expressions with implementation-defined (positive) values that are less
than or equal to those shown:

- the difference between 1 and the least value greater than 1 that is
representable in the given floating point type, b1− p

Więc powyższe nie zostawia już chyba wątpliwości, która wartość jest
poprawna?
Post by slawek
Post by Michoo
I zazwyczaj nie ma to znaczenia. Nikt nie robi poważnej numeryki
opierając się o to, że na x86 połowa epsilona double wystarcza.
Wyznanie, że mało znasz ludzi robiących obliczenia numeryczne,
Nie aż tak dużo - to fakt.
Post by slawek
a w
szczególności wśród tych osób nikogo takiego co przykłada jakiekolwiek
znaczenie do wartości epsilon?
Nie. Epsilon jako dokładność obliczeń (do czego się odwoływałeś) używa
się ewentualnie w opisie algorytmu. Jako wartość w programie przyjmuje
się różne EPS (odległość miedzy wartościami) zależnie od zakresu na
którym się pracuje, zazwyczaj do określenia relacji równoważności i są
to setki albo tysiące razy większe wartości niż EPS_DOUBLE podczas
liczenia na double.

W niektórych przypadkach gdy obliczenia są robione w okolicy "granic"
typów aby zachować informację o rozmiarze błędu używa się przedziałów.
--
Pozdrawiam
Michoo
slawek
2012-11-05 18:53:06 UTC
Permalink
Post by Michoo
ISO/IEC 9899:TC3
Ok. Trzeba będzie sprostować w kilku miejscach - i powołanie się na
/konkretny/ standard ułatwi sprawę.
Roman W
2012-11-05 23:57:48 UTC
Permalink
Nie. Epsilon jako dokadno oblicze (do czego si odwoywae)
uywa
si ewentualnie w opisie algorytmu. Jako warto w programie
przyjmuje
si róne EPS (odlego miedzy wartociami) zalenie od zakresu na
którym si pracuje, zazwyczaj do okrelenia relacji równowanoci i
s
to setki albo tysice razy wiksze wartoci ni EPS_DOUBLE podczas
liczenia na double.
Widziaem sytuacje, kiedy zmiana funkcji z inline na nie-inline
powodowaa wzgledna zmian kocowego wyniku o 1e-13.

RW
bartekltg
2012-11-06 02:28:35 UTC
Permalink
Post by Michoo
Nie. Epsilon jako dokadno oblicze (do czego si odwoywae)
uywa
si ewentualnie w opisie algorytmu. Jako warto w programie
przyjmuje
si róne EPS (odlego miedzy wartociami) zalenie od zakresu na
którym si pracuje, zazwyczaj do okrelenia relacji równowanoci i
s
to setki albo tysice razy wiksze wartoci ni EPS_DOUBLE podczas
liczenia na double.
Widziaem sytuacje, kiedy zmiana funkcji z inline na nie-inline
powodowaa wzgledna zmian kocowego wyniku o 1e-13.
Obcinanie pośrednich wyników do double (przy wejściu/wyjśćiu funkcji)
kontra liczenie wszystkiego w rejestrach koprocesora, czy coś głębszego?

pzdr
bartekltg
Roman W
2012-11-06 05:35:25 UTC
Permalink
Obcinanie porednich wyników do double (przy wejciu/wyjiu
funkcji)
kontra liczenie wszystkiego w rejestrach koprocesora, czy co
gbszego?

Moe to? Albo inna kolejno oblicze. To byo C++ pod Windows.

RW
AK
2012-11-06 10:31:24 UTC
Permalink
Post by bartekltg
Obcinanie pośrednich wyników do double (przy wejściu/wyjśćiu funkcji)
kontra liczenie wszystkiego w rejestrach koprocesora, czy coś głębszego?
Napewno to + mozliwa w tym przypadku (czyli funkcji inline) optymalizacja calosciowa
wyrazenia (parse-tree, semikodu - i kodu wynikowego/maszynowego).

Poniewaz inline to tylko sugestia a nie oblig, wiec w praktyce moga (i dzieja sie)
"cuda" np. w debug sa inne wyniki fp niz w release, niektore funkcje po dodaniu
niewinnej linijki daja daja nieco inne wyniki itp itd.
W tym kontekscie "problem" buraka hrabiego (jak i on sam) z DBL_EPSILON jest
po prostu smieszny.

AK
Michoo
2012-11-06 11:02:50 UTC
Permalink
Post by AK
Poniewaz inline to tylko sugestia a nie oblig, wiec w praktyce moga (i dzieja sie)
"cuda" np. w debug sa inne wyniki fp niz w release, niektore funkcje po dodaniu
niewinnej linijki daja daja nieco inne wyniki itp itd.
boost::Interval Arithmetic Library - wychodzi ~2x wolniej, ale pozwala
całkiem nieźle oszacować, czy uzyskany wynik jest czymś więcej niż
nagromadzeniem błędów obliczeniowych.
--
Pozdrawiam
Michoo
Roman W
2012-11-06 12:32:31 UTC
Permalink
Post by Michoo
Post by AK
Poniewaz inline to tylko sugestia a nie oblig, wiec w praktyce moga (i
dzieja sie)
"cuda" np. w debug sa inne wyniki fp niz w release, niektore funkcje po
dodaniu
niewinnej linijki daja daja nieco inne wyniki itp itd.
boost::Interval Arithmetic Library - wychodzi ~2x wolniej, ale pozwala
całkiem nieźle oszacować, czy uzyskany wynik jest czymś więcej niż
nagromadzeniem błędów obliczeniowych.
Da sie to "wrzucic" do starego kodu bez zmudnego przepisywania kazdej linijki?

RW
Michoo
2012-11-06 13:47:26 UTC
Permalink
Post by Roman W
Post by Michoo
boost::Interval Arithmetic Library - wychodzi ~2x wolniej, ale pozwala
całkiem nieźle oszacować, czy uzyskany wynik jest czymś więcej niż
nagromadzeniem błędów obliczeniowych.
Da sie to "wrzucic" do starego kodu bez zmudnego przepisywania kazdej linijki?
Musiałbyś zrobić wrapper i poczarować preprocesorem, ale jest spora
szansa, ze by się dało w miarę "gładko". Problemem mogą być zewnętrzne
biblioteki/funkcje, które wymagają zwykłego double a nie przedziału -
można dodać operator konwersji + #warning.

I z tego co widzę w starym kodzie trzeba napisać samemu funkcje do
potęgowania i pierwiastkowania dwoma przedziałami.
--
Pozdrawiam
Michoo
AK
2012-11-04 22:00:57 UTC
Permalink
Masz 100% racji - w komunistycznym systemie, na sprzęcie made in republika ludowa
Glupi zburaczaly palancie :)
Odra 1325/1305 to byl klon rodziny jak najbardziej angielskiego komputera
(a wlasciwie calej rodziny) ICL 1900 :)

PS: I nie wyjezdzaj mi tu z komunizmem, bo moje inicjaly nie sa przypadkowe.

AK
slawek
2012-11-05 11:14:41 UTC
Permalink
Post by AK
Glupi zburaczaly palancie :)
Nie pisz opinii na swój temat - to zdecydowanie NTG.
Post by AK
Odra 1325/1305 to byl klon rodziny jak najbardziej angielskiego komputera
(a wlasciwie calej rodziny) ICL 1900 :)
Delikatnie ujmując - kopia. Używane bywało tu i owdzie (ba, nawet był
program robiący papier toaletowy - maketape się nazywał).
Post by AK
PS: I nie wyjezdzaj mi tu z komunizmem, bo moje inicjaly nie sa przypadkowe.
Oczywiście że nie są - inicjały to pierwsze litery z imienia i nazwiska,
nazwisko jest z dużym prawdopodobieństwem po ojcu ew. matce, imię to albo
jaki święty, albo inna tradycja. Gdzie tu przypadkowość? Chyba tylko w tym,
że kiedyś gdzieś była taka organizacja itd. - no, łatwiej i przyjemniej mieć
inicjały AK niż ZAIKSS czy UPA (np. Urszula Partycja A.).
AK
2012-11-05 15:17:41 UTC
Permalink
Post by slawek
Nie pisz opinii na swój temat - to zdecydowanie NTG.
Nie. Ja pisze o Tobie.

Burakiem (tak tak, mimo ze "hrabią" to jednak burakiem), chamem
i palantem zaczales byc dla mnie od momentu przeczytania tych
twych slow do Bartka:

"
@bartekltg
Post by slawek
Będziesz miał syf. To nie sa integery, nie powinno się działać
na 'ostatnich bitach'.
@slawek
Nie będę miał. Nie znam twojej siostry. Te zdania mają tyle ze sobą
wspólnego, co podany przykład z liczbami integer.
"
i pozostaniesz dopóki nie przeczytam slow twych przeprosin do Bartka.
Nie trac czasu na sazniste "tlumaczace" cie epistoly jak poprzednio.
Mnie nie przekonaly kompletnie (mam nadzieje ze wiekszosci grupowiczow tez nie).
Tym bardziej, ze (jak sam sie chwalisz), masz "niebieska krew".
Do momentu ew. przeprosin bede dalej w stosunku do ciebie uzywal
tych zasadnych epitetow.
Co nie znaczy, ze bede sie jeszcze do ciebie odzywal.

AK
Marek Borowski
2012-11-05 15:33:32 UTC
Permalink
Post by AK
Post by slawek
Nie pisz opinii na swój temat - to zdecydowanie NTG.
Nie. Ja pisze o Tobie.
Burakiem (tak tak, mimo ze "hrabią" to jednak burakiem), chamem
i palantem zaczales byc dla mnie od momentu przeczytania tych
"
@bartekltg
Post by slawek
Będziesz miał syf. To nie sa integery, nie powinno się działać
na 'ostatnich bitach'.
@slawek
Nie będę miał. Nie znam twojej siostry. Te zdania mają tyle ze sobą
wspólnego, co podany przykład z liczbami integer.
"
i pozostaniesz dopóki nie przeczytam slow twych przeprosin do Bartka.
Nie trac czasu na sazniste "tlumaczace" cie epistoly jak poprzednio.
Mnie nie przekonaly kompletnie (mam nadzieje ze wiekszosci grupowiczow tez nie).
Tym bardziej, ze (jak sam sie chwalisz), masz "niebieska krew".
Do momentu ew. przeprosin bede dalej w stosunku do ciebie uzywal
tych zasadnych epitetow.
Co nie znaczy, ze bede sie jeszcze do ciebie odzywal.
Daj spokoj, osoba o ktorej piszesz to jakis malutki czlowiek,
odreagowujacy swoje frustracje z realu w necie, ktory w kazdym poscie
obraza ludzi. Bardzo dziwie sie ze wogole ktos chce z nim wspolpracowac.
Napisze cos co moze powiekszyc jego rozdete ego (o ile wogole da sie
takiemu bufonowi je powiekszyc) - w jednym jest wyjatkowy, udalo mu sie
jako jedynej osobie przekonac mnie do dopisania jej do KF, co zreszta
polecam wszystkim.

Pozdrawiam

Marek
slawek
2012-11-05 18:38:58 UTC
Permalink
Post by Marek Borowski
takiemu bufonowi je powiekszyc) - w jednym jest wyjatkowy, udalo mu sie
jako jedynej osobie przekonac mnie do dopisania jej do KF, co zreszta
Bardzo mądre zalecenie - jeżeli ktoś jest bufonem i/lub lemingiem - to od
razu powinien mnie dopisać do KF.
slawek
2012-11-05 19:32:15 UTC
Permalink
Post by AK
Burakiem (tak tak, mimo ze "hrabią" to jednak burakiem), chamem
i palantem zaczales byc dla mnie od momentu przeczytania tych
Piszesz nie na temat (przypominam, tematem jest DBL_EPSILON z float.h i
hasło z Wikipedii).
Post by AK
Do momentu ew. przeprosin bede dalej w stosunku do ciebie uzywal
tych zasadnych epitetow.
Wyraźnie masz problemy. Ale to są twoje problemy, z twoją samooceną. NTG
kenobi
2012-11-05 19:46:09 UTC
Permalink
Post by slawek
Wyraźnie masz problemy. Ale to są twoje problemy, z twoją samooceną. NTG
to sa wszystko problemy spod litery d (d r e dokladniej) Imo lepiej odeslac dresów do dresa a siebie do assemblera (i am doin it such way)
[choc ostatnio tluke nie tyle asma co raczej ogla]
kenobi
2012-11-05 21:11:27 UTC
Permalink
Post by kenobi
to sa wszystko problemy spod litery d (d r e dokladniej) Imo lepiej odeslac dresów do dresa a siebie do assemblera (i am doin it such way)
wogole u mnie w borlandowym naglowku sa takie stale co do epsilonow

#define DBL_EPSILON 2.2204460492503131E-16
#define FLT_EPSILON 1.19209290E-07F
#define LDBL_EPSILON 1.084202172485504434e-019L

gdyby ktos wkleil naglowki float.h z GCC i MSVS (najlepiej całe) to chetnie bym je sobie zobaczyłi porownał
Roman W
2012-11-02 09:58:06 UTC
Permalink
Post by AK
Bo prawdziwy epsilon moj drogi zburaczaly "hrabio" (vide chamski
wtret do Bartka o siostrze - twoich przeprosin nie zauwazylem) _zawsze_
powinno sie dobierac w scislym zwiazku z natura problemu/algorytmu
numerycznego i z natury swej powinien on byc o wiele wyzszy
od precyzji maszynowej.
Wystarczy wynik obliczen przepuscic pare razy przez jakies exp, pow czy log i epsilonik z 1E-16 robi sie 1E-13.

RW
AK
2012-11-04 21:50:49 UTC
Permalink
Post by Roman W
Wystarczy wynik obliczen przepuscic pare razy przez jakies exp, pow
czy log i epsilonik z 1E-16 robi sie 1E-13.
Doklanie. Przeciez o tym w gruncie rzeczy mowie (stad to umowne pomnozenie przez 100).
Poza tym zburaczaly hrabia slawek chyba zapomnial o czyms tak podstawowym problemie
w numeryce jak kumulacja bledow.
Przy zlym algorytmie (nie dbajacym o to aby ta kumulacja sie znosila) pomnozenie "maszynowego"
epsilona nawet przez przyslowiowy milion nie wystarczy :)

Ja sie juz na tym (numeryce/matmie) neistety nie znam (numeryka zajmowalem sie rowno 25lat temu),
ale skupainie sie na maszynowym epsilonie chyba jednak i dzis charakretyzuje (przynajmniej powinno)
numeryczne zbureczanie.

AK
slawek
2012-11-05 10:52:16 UTC
Permalink
Post by AK
Przy zlym algorytmie (nie dbajacym o to aby ta kumulacja sie znosila)
pomnozenie "maszynowego"
epsilona nawet przez przyslowiowy milion nie wystarczy :)
O, to czekam na program przewidujący kumulację w Lotto. ;)
Post by AK
Ja sie juz na tym (numeryce/matmie) neistety nie znam (numeryka zajmowalem
sie rowno 25lat temu),
ale skupainie sie na maszynowym epsilonie chyba jednak i dzis
charakretyzuje (przynajmniej powinno)
numeryczne zbureczanie.
A konkretnie czym się zajmowałeś 25 lat temu?

Rozumiem, że za takie samo "zbureczanie" (pisownię pozostawiłem bez zmian)
uważasz np. CFL?
Roman W
2012-11-05 23:53:27 UTC
Permalink
Rozumiem, e za takie samo "zbureczanie" (pisowni pozostawiem bez
zmian)
uwaasz np. CFL?
Zajmowanie si fajnymi rzeczami nie czyni automatycznie zajmujcego
si fajnym czowiekiem.

RW
AK
2012-11-02 08:08:36 UTC
Permalink
Post by bartekltg
Błędem jest w ogóle działanie na takich zakresach.
To chyba podstawy 'numerków'.
Ano wlasnie ! (slowem sedno).

AK
slawek
2012-11-02 09:11:39 UTC
Permalink
Użytkownik "AK" napisał w wiadomości grup
Post by AK
Ano wlasnie ! (slowem sedno).
A konkretnie? Co masz na myśli?

Ja rozumiem, że niektórzy nie wyszli poza liczeniem sprzedanych jabłek (ew.
sprzedanych kredek, komputerów, ton węgla). I że do tego wystarczą liczby z
dwoma miejscami po przecinku.

Jednak tym razem - przypomina się "baza danych szlauchów i kaloszy" - nie
dyskutujemy na ten temat. Tylko na temat: "jak to możliwe, że epsilon w
float.h jest dwukrotnie zawyżony wobec tego jaką wartość trywialnie łatwo
wyliczyć opierając się na podanej definicji". Oraz na temat: "czy należy
poprawić hasło w Wikipedii, w której jest epsilon dwa razy mniejszy niż we
float.h".

No, ale rozumiem że na poziomie abstrakcji jaki sobą reprezentujesz, to dwa
razy w tę... czy dwa razy we w tę... to mało istotne, prawda?
bartekltg
2012-11-01 13:49:57 UTC
Permalink
Post by kenobi
Ciekawe, ale dlaczego to jest dokladnie podwojona
wartosc epsilona? Z poczatku wydawalo mni sie ze slowo double odnosi sie wlasnie do tego (a nie do typu double) i ze ta podwojna wartosc ma jakiej uzasadnienie
Z powodu niedoczytania i niejasnej definicji (definicja w floath.h
jest myląca, ale ta w eps w matalbie powinna wszystko wyjaśnić).

Bierzemy 1 i nasz epsylon_s = 1.11022324691088480000E-16.

Odpalamy:
ee=1.11022324691088480000E-16
a=1+ee
roznica = a-1

Wychodzi:
ee =
1.1102e-016
a =
1.0000
roznica =
2.2204e-016

Odległość między 1 a następną liczbą double wynosi 2.2204e-016,
i to jest prawdziwa dokładność maszynowa.

Dlaczego ten dwa razy mniejszy działa dla 'testu' 1+eps != 1?
Koprocesor Zaokrąglanie. Koprocesor działa na ciut dłuższych
liczbach niż 64bity (80bitów na x86) dodaje bez problemu 1 do
epsylona sławka, następnie rzutuje na double. A, że jest w połowie
drogi do następnej liczby zapisywalnej w double, zaokrągla w górę.
I różnica wychodzi 2.2204e-016.

Ale nie znajdziesz takiej liczby x>1, aby |x-1|= 1.1102e-016

Co bardziej zasługuje na nazwę epsylon maszynowy,
1+eps != 1 czy eps = min_{x>1} (x-1)
to dyskusja o wyższości świat przesilenia zimowego na marsie
i rocznicy uśpienia chutuchtu.

I tak używamy raczej liczb typu 100*eps, gdzie to 100 jest bardzo
orientacyjne czy, częściej i większą podbudową teoretyczną, np
sqrt(eps).
Jeśli nasz program 'działa' dla jednego z tych epsyllonów,
a nie "działa" dla drugiego, to i tak trzeba pomyśleć albo
użyć większej precyzji.


A, żeby było zabawniej:
ee=1.11022324691088480000E-16/2 %dwa razy mniej!
a=1-ee
roznica = a-1

ee =
5.5511e-017
a =
1.0000
roznica =
-1.1102e-016

:-)


pzdr
bartekltg
AK
2012-11-02 08:05:33 UTC
Permalink
Jednak zaglądając do float.h w MS VS C++ można znaleźć definicję DBL_EPSILON, wraz ze stosownym
komentarzem, 2.22044604925031310000E-016. Jest to niemal 2 razy więcej, niż naprawdę wynosi
epsilon (obliczony właśnie programem skompilowanym w MSVS C++).
I bardzo dobrze, ze 2 razy wiecej.

AK.
slawek
2012-11-02 08:49:19 UTC
Permalink
Użytkownik "AK" napisał w wiadomości grup
Post by AK
I bardzo dobrze, ze 2 razy wiecej.
Potrafisz to uzasadnić?

Zwłaszcza w kontekście np. takiego fragmentu:

if (x >= DBL_EPSILON)
s = 1.0 + x ;
else
s = 1.0;

Jeżeli x jest typu double, to przy prawidłowej wartości DBL_EPSILON wszystko
jest ok, czyli tak, jak to wynika z definicji (patrz np. Numerical Recipes).

Poprawna wartość to ta która jest zgodna z wybraną definicją. Definicja MS
sprowadza się do inf { x : op(1,x) > 1 } .

W przeciwnym razie musielibyśmy oboje się zgodzić, że twój szef ma prawo np.
wypłacić ci tylko połowę pensji - "definicja" jaka jest w umowie o pracę
jest przecież tylko dla picu - dwa razy więcej, dwa razy mniej - co za
problem?
kenobi
2012-11-02 11:28:34 UTC
Permalink
Post by slawek
Użytkownik "AK" napisał w wiadomości grup
Post by AK
I bardzo dobrze, ze 2 razy wiecej.
Potrafisz to uzasadnić?
if (x >= DBL_EPSILON)
s = 1.0 + x ;
else
s = 1.0;
Jeżeli x jest typu double, to przy prawidłowej wartości DBL_EPSILON wszystko
jest ok, czyli tak, jak to wynika z definicji (patrz np. Numerical Recipes).
Poprawna wartość to ta która jest zgodna z wybraną definicją. Definicja MS
sprowadza się do inf { x : op(1,x) > 1 } .
W przeciwnym razie musielibyśmy oboje się zgodzić, że twój szef ma prawo np.
wypłacić ci tylko połowę pensji - "definicja" jaka jest w umowie o pracę
jest przecież tylko dla picu - dwa razy więcej, dwa razy mniej - co za
problem?
kwestia moze byc w tym ze tamten tekst
z naglowka to moze byc nie tyle definicja
co komentarz przyblizona ilustracja

np mozliwe ze wynik (1 + epsilon != 1)
moze zalezec od jakiegos konfigurowalnego
stanu fpu (choc nie wiem co by to moglo
byc, sa rozne sposoby zaokraglania wynikow
przy dodawaniu doubli? chyba nie)

pozatym jednak niechybnie masz racje
jesli okazuje sie ze ten 2.2 nie jest
najmniejsza liczba, tylko 1.1 tez dziala;

moze jednak 2.2 dziala w jakichs innych
wypadkach (albo inny stan fpu albo jakies
inne przypadki do ktorych potocznie
moglbbyc uzywany taki epsilon i 1.1
tam sie nie lapie)
kenobi
2012-11-02 11:36:56 UTC
Permalink
przy tym jak rozumiem taki epsilon moze byc uzyteczny przy sprawdzaniu bledow zkresu
(a raczej wartos ie tym czasem zajac bo
jak nie to bledy moga po prostu wchodzic,
nawet w grafice mozna miec male rozjazdy i czlowiek o tym nie wie , a bez nich moglo by wygladac lepiej

Choc i tak nie wiem czy asserty dla takiego zakresu robi sie to wlasnie przy pomocy tej stalej czy inaczej
slawek
2012-11-02 14:59:15 UTC
Permalink
Użytkownik "kenobi" napisał w wiadomości grup
Post by kenobi
nawet w grafice mozna miec male rozjazdy i czlowiek o tym nie wie , a bez
nich moglo by wygladac lepiej
Z mojego doświadczenia wiem, że "małe rozjazdy" nie mają znaczenia jeżeli:

A. nie kumulują się;
B. nie są "dziurami" - np. dwie "niemal" stykające się ściany "trochę źle
zszyte" - i np. przeciwnik widzi nas jakby miał RTG w oczach.
slawek
2012-11-02 14:54:31 UTC
Permalink
Użytkownik "kenobi" napisał w wiadomości grup
Post by kenobi
pozatym jednak niechybnie masz racje
jesli okazuje sie ze ten 2.2 nie jest
najmniejsza liczba, tylko 1.1 tez dziala;
No właśnie rzecz w tym, że mam-i-nie-mam. Spróbuję uporządkować, ale
potrzebna mi jest definicja op(a,b). Funkcję op(a,b) definiuję jako wynik
"dodawania" wykonywanej na danym komputerze. W ten sposób nie musi być nawet
op(2,2) == 4, bo op(a,b) nie jest sumą liczb a+b w sensie matematycznym.

I teraz mamy 3 "epsilony":

1. Liczbę x, która jest najmniejszą liczbą spełniającą nierówność op( 1.0,
x ) > 1.0 .
2. Liczbę y, która jest największą liczba spełniającą równanie op( 1.0, y )
== 1.0 .
3. Liczbę z, która wynosi z = q - 1.0, gdzie q jest najmniejszą liczbą
zapisywalną w określony sposób i spełniającą warunek q > 1.0 .

Uwaga: odejmowanie w pkt. 3. należy rozumieć abstrakcyjnie, czyli ściśle
matematycznie.

Liczby x oraz y są różne na n-tym miejscu po przecinku i dlatego traktuję
je - choć niesłusznie - jako ten sam epsilon. Gdyby zwiększać ilość bitów
mantysy do nieskończoności, to granicznie stałyby się identyczne (i równe
zeru).

Liczba z jest, w bardzo dobrym przybliżeniu, 2 razy większa niż z. I tę
właśnie liczbę Bartek nazywa epsilonem. Ok, też można. Choć jest to jednak
inna definicja niż np. w Numerical Recipes, czyli dość popularnym
podręczniku nt. metod numerycznych (takim sobie, ale znacznie lepszym niż
np. podręcznik Jankowskich) i niż "miał na myśli artysta" uwieczniający się
komentarzem we float.h.

Fakt, że z jest około dwukrotnie większy niż x jest trudno wytłumaczalny
bez - czego właśnie Bartek nie potrafił wyjaśnić - wiedzy o tym, że
obliczenia FPU są robione na 80 bitowych a nie 64 bitowych liczbach float
point. Tzn. normalne liczby double mają mantysę 53 bitową, ale wewnętrznie
FPU (zmutowany Intel 80287) liczy z mantysą 63 bitową. Zaokrąglanie op(1,x)
następuje "do najbliższej", więc w ten sposób w jako wynik osiągana jest
liczba q > 1.0 - "brakującą połówkę z" dostajemy w trakcie konwersji z
mantysy 63 bitowej na 53 bitową.

Przy "różnych opcjach kompilatora(ów)" da się wymusić czasem jakieś double
double, quarduple czy extended - oraz rygorystyczne obcinanie dokładności
FPU do 53 bitów. Istnieją też prawdziwe procesory 128 bitowe i takie tam.
Więc rzeczywiście nie jest bezpiecznie polegać na wstępnie ustalonym
DBL_EPSILON - a zwłaszcza (co już pisałem) brać dosłownie wszystkich cyferek
jakie tam we float.h są wypisane.

W Wikipedii jest jak wół epsilon 1.11E-16 (dla double), ale na tej samej
stronie WWW jest przykład w Phytonie z wynikiem 2.22E-16. Już samo to
wymagałoby sprostowania, przecież Wikipedia nie jest czymś czego nie można
poprawiać - zwłaszcza jeżeli się aspiruje do bycia - jak Bartek - ekspertem
w dziedzinie.
Tomasz Sowa
2012-11-03 10:48:52 UTC
Permalink
Post by slawek
Tzw. maszynowy epsilon (see Wikipedia) wynosi nie więcej niż 1.111E-016 dla
liczb 64-bitowych.
Na wikipedii jest 2.220446e-16 (zjedź na dół do przykładu)
Post by slawek
Taki wynik łatwo otrzymać nawet naiwnym algorytmem, w
którym po kolei sprawdzane są w pętli kolejne wartości epsilon - każda
kolejna nieco (o ułamek procenta) mniejsza od poprzedniej.
A po co taki naiwny algorytm? definicja maszynowego epsilon chyba jest
jasna?
Post by slawek
Algorytm "fast"
O(1) patrz poniżej
Post by slawek
adaptacyjnie zmienia krok itd. - nie ma to znacznego wypływu na wynik, ale
liczba kroków jest znacznie mniejsza.
Jednak zaglądając do float.h w MS VS C++ można znaleźć definicję
DBL_EPSILON, wraz ze stosownym komentarzem, 2.22044604925031310000E-016.
I jest to prawidłowa wartość.
Post by slawek
Jest to niemal 2 razy więcej, niż naprawdę wynosi epsilon (obliczony właśnie
programem skompilowanym w MSVS C++). "This is not a bug, this is
inaccuracy" - chciałoby się powiedzieć.
Pokaż ten program.
Post by slawek
Zaglądamy dalej - Matlab - tak ostatnio chwalony - ma wbudowaną funkcję
eps - zgadnijcie co zwraca eps jako wynik liczbowy? Tak, też się zdziwiłem -
przecież Matlab to Matlab.
Jeszcze raz rzut oka do Wikipedii - jest sobie wyraźnie dobra wartość
epsilona dla double w tabelce - ale już np. program w Phytonie i wyniki z
niego - znowu błędne 2.22E-16 . I nie jest to "wina Phytona" - ale po prostu
błąd w programie.
"Phytonowcy", staff MS i ludzie z MathWorks popełnili jeden i ten sam błąd -
dzielili przez dwa. Ciąg wartości x[n], jakie otrzymywali, dla dostatecznie
dużego n nie spełniał nierówności 1.0+x[n] > 1.0.
Nie wiem co tu jest do dzielenia, aby obliczyć maszynowe epsilon nic nie
trzeba dzielić, przykład:

#include <iostream>
#include <stdint.h>
#include <iomanip>

int main()
{
union
{
double f;
uint64_t i;
} u1, u2, u3;


u1.i = 0x3ff0000000000000ul;
// jeden (exponent na 1023 mantysa na zero -- jeden bit z przodu
// mantysy jest domniemany)

u2.i = 0x3ff0000000000001ul;
// jeden i ciupka (ostatni bit mantysy na jeden i jeden bit z przodu
// domniemany)

u3.f = u2.f - u1.f;


std::cout << "Maszynowe epsilon: " << std::setprecision(18) <<
u3.f << std::endl;
}

/home/tomek/roboczy/test$ g++ -O2 -o test test.cpp && ./test
Maszynowe epsilon: 2.22044604925031308e-16

Oczywiście nie widzę sensu wypisywania tej wartości jako decimal (to
tylko przybliżenie).
W C++ jako stałą możesz mieć w ten sposób:
std::cout << std::numeric_limits<double>::epsilon() << std::endl;
--
Tomek
http://www.ttmath.org
slawek
2012-11-03 11:54:25 UTC
Permalink
Użytkownik "Tomasz Sowa" napisał w wiadomości grup
Post by Tomasz Sowa
Na wikipedii jest 2.220446e-16 (zjedź na dół do przykładu)
A ty przeczytaj tabelę u góry (na tej samej stronie Wikipedii).
Jak na to nie patrzeć - trzeba poprawić - albo u góry, albo u dołu, albo w
obu miejscach.
Post by Tomasz Sowa
A po co taki naiwny algorytm? definicja maszynowego epsilon chyba jest
jasna?
A po co lepszy? Skoro i tak liczy się w mniej niż sekundę? (Czyli o parę
rzędów wielkości krócej, niż trwało np. napisanie przez ciebie tekstu?)
Post by Tomasz Sowa
I jest to prawidłowa wartość.
Możliwe. Pod warunkiem, że przyjmiemy inną definicję niż podana w samym
pliku float.h.

Wniosek - albo definicja w pliku float.h (z pakietu MSVS) jest błędna, albo
wartość w pliku float.h (ibidem) jest błędna, albo obie są błędne.
I to właśnie (podobnie jak hasło w Wikipedii) wymagałoby wyprostowania.
Post by Tomasz Sowa
Pokaż ten program.
Nie będę ciebie obrażał podejrzeniem, że nie potrafisz. Do sprawdzenia, że
1.0+1.5E-16 > 1.0 to wystarczy ci jedna linijka zaczynająca się od cout.
Post by Tomasz Sowa
Nie wiem co tu jest do dzielenia, aby obliczyć maszynowe epsilon nic nie
Owszem, ale ty nie obliczasz epsilona jako inf { x in R : op(1,x) > 1 },
czyli jako najmniejszej liczby, która w wyniku "operacji dodawania
maszynowego" do liczby 1 daje wynik większy niż 1. Zajrzyj sobie do
Teukolsky'ego - oczywiście masz prawo twierdzić, że są tam bzdury. Ale w
takim razie warto napisać do Teukolsky'ego - i pouczyć go jak ma zmienić
fragment rozdziału.

Prawdą jest (w opisanych warunkach), że (double)1.0 + (double)2.22E-16 >
(double)1.0 , ale prawdą jest też, że np. (double)1.0 + (double)1.5E-16 >
(double)1.0E-16.

Z mojego punktu widzenia, jeżeli mam macierz 1000x1000 a chcę przekształcić
ja na macierz rzadką przeglądając jej elementy i uznając za zerowe te, które
są mniejsze niż eps, to lepiej jeżeli wartości równe DLB_EPSILON zostaną jak
są, bo jeżeli odrzucę pół miliona takich - to może polecieć mi w porywach
pięć miejsc znaczących. Przy epsilon = 1.11E-16 czy uznam za zero, czy
zostawię jak są - wynik sumowania z 1.0 będzie jednakowy i nic nie stracę
jeżeli liczby były 64-bitowe z 53-bitową mantysą.
Tomasz Sowa
2012-11-03 13:07:57 UTC
Permalink
Post by Tomasz Sowa
Na wikipedii jest 2.220446e-16 (zjedź na dół do przykładu)
A ty przeczytaj tabelę u góry (na tej samej stronie Wikipedii). Jak
na to nie patrzeć - trzeba poprawić - albo u góry, albo u dołu, albo
w obu miejscach.
Poprawione, ktoś sobie założył że ma 53 bity precyzji a tak naprawdę
jest 52 plus jeden domniemany z przodu ale on 'nie działa w tym
przypadku'. Wrzuciłem także do części talk dowód tego i przykłady
w c++: http://en.wikipedia.org/wiki/Talk:Machine_epsilon
Na razie poprawione dla binary32 i binary64 jak znajdę jutro czas to
przyjrzę się pozostałym.
Post by Tomasz Sowa
A po co taki naiwny algorytm? definicja maszynowego epsilon chyba
jest jasna?
A po co lepszy? Skoro i tak liczy się w mniej niż sekundę? (Czyli o
parę rzędów wielkości krócej, niż trwało np. napisanie przez ciebie
tekstu?)
Bo popełniasz błąd który się propaguje w każdej iteracji algorytmu.
Post by Tomasz Sowa
I jest to prawidłowa wartość.
Możliwe. Pod warunkiem, że przyjmiemy inną definicję niż podana w
samym pliku float.h.
Wniosek - albo definicja w pliku float.h (z pakietu MSVS) jest
błędna, albo wartość w pliku float.h (ibidem) jest błędna, albo obie
są błędne. I to właśnie (podobnie jak hasło w Wikipedii) wymagałoby
wyprostowania.
Post by Tomasz Sowa
Pokaż ten program.
Nie będę ciebie obrażał podejrzeniem, że nie potrafisz. Do
sprawdzenia, że 1.0+1.5E-16 > 1.0 to wystarczy ci jedna linijka
zaczynająca się od cout.
Właśnie mówie pokaż program, bo pewnie przykład robisz obliczając na 80
bitach ;)
Post by Tomasz Sowa
Nie wiem co tu jest do dzielenia, aby obliczyć maszynowe epsilon
Owszem, ale ty nie obliczasz epsilona jako inf { x in R : op(1,x) >
1 }, czyli jako najmniejszej liczby, która w wyniku "operacji
dodawania maszynowego" do liczby 1 daje wynik większy niż 1. Zajrzyj
sobie do Teukolsky'ego - oczywiście masz prawo twierdzić, że są tam
bzdury. Ale w takim razie warto napisać do Teukolsky'ego - i pouczyć
go jak ma zmienić fragment rozdziału.
Definicja z dodawaniem nie jest dobra, trzeba uwzględnić zaokrąglanie.
Możesz dodawać do jedynki 'bardzo malutką wartość' a zaokrąglanie masz
ustawione w górę i wartość ci wyjdzie różna od jeden. Ale to co dodałeś
nie będzie prawidłowym maszynowym epsilonem.

Lepsza jest definicja że maszynowy epsilon dla danego typu to po prostu
różnica
pomiędzy następną *reprezentowalną* liczbą w tym typie za jedynką a samą
jedynką.
Prawdą jest (w opisanych warunkach), że (double)1.0 +
(double)2.22E-16 > (double)1.0 , ale prawdą jest też, że np.
(double)1.0 + (double)1.5E-16 > (double)1.0E-16.
W procesorze masz 80 bitów a nie 64.
--
Tomek
http://www.ttmath.org
slawek
2012-11-03 15:10:07 UTC
Permalink
Użytkownik "Tomasz Sowa" napisał w wiadomości grup
Post by Tomasz Sowa
Poprawione, ktoś sobie założył że ma 53 bity precyzji a tak naprawdę
I dobrze. Przynajmniej jest jakaś spójność. Zajrzałeś wcześniej do standardu
IEEE-754 ? Referencje do źródeł?
Post by Tomasz Sowa
Bo popełniasz błąd który się propaguje w każdej iteracji algorytmu.
Nie ma błędu. Za każdym razem jest na nowo sprawdzanie 1.0+eps > 1.0, tj.
pętla while(1.0 + eps > 1.0) {...}

Nawet jeżeli były jakieś zaokrąglenia wcześniej itd. ("propagował się") - to
spełnienie/niespełnienie warunku zależy wyłącznie od aktualnej wartości
("nie widzi historii").
Post by Tomasz Sowa
Właśnie mówie pokaż program, bo pewnie przykład robisz obliczając na 80
bitach ;)
Robię obliczenia na przeciętnych PC przy domyślnych ustawieniach
kompilatora - z którym to dostarczany jest plik float.h z DBL_EPSILON takim
jaki tam jest.

To chyba nie moją rolą jest obudować ten DBL_EPSILON jakimiś ifdef-ami, albo
przynajmniej dać komentarz, kiedy jego wartość jest sensowna? ;)
Post by Tomasz Sowa
Definicja z dodawaniem nie jest dobra, trzeba uwzględnić zaokrąglanie.
Definicja z dodawaniem JEST DOBRA - właśnie dlatego, że UWZGLĘDNIA
DODAWANIE. Jako end-usera nie obchodzi mnie, ile i jakich bitów jest gdzie -
mogą być nawet analogowe napięcia w miliwoltach, mogą być natężenia
przepływu syropu, mogą być jakieś q-bity czy p-bity. Obchodzi mnie tylko,
kiedy 1+x policzone na danej maszynce da w okienku wyników 1, choć x nie
było zerem.
Post by Tomasz Sowa
ustawione w górę i wartość ci wyjdzie różna od jeden. Ale to co dodałeś
nie będzie prawidłowym maszynowym epsilonem.
To co ty nazywasz "maszynowym epsilonem" nie jest "maszynowe" - ale
zwyczajnie "pamięciowe". Jest wielkością charakterystyczną dla /sposóbu/
zapisu liczb w pamięci (tj. w RAM, w rejestrach FPU itd.)
Post by Tomasz Sowa
Lepsza jest definicja że maszynowy epsilon dla danego typu to po prostu
To nie jest lepsza definicja - choć i nie gorsza. To po prostu inna
definicja.
Post by Tomasz Sowa
W procesorze masz 80 bitów a nie 64.
Niekoniecznie. Są różne procesory i różne tryby ich pracy.
Tomasz Sowa
2012-11-05 20:35:47 UTC
Permalink
Post by slawek
Post by Tomasz Sowa
Bo popełniasz błąd który się propaguje w każdej iteracji algorytmu.
Nie ma błędu. Za każdym razem jest na nowo sprawdzanie 1.0+eps > 1.0,
tj. pętla while(1.0 + eps > 1.0) {...}
a no, tak sądziłem, sprawdź poniższy program

#include <iostream>
#include <stdint.h>
#include <iomanip>

template<typename float_t, typename int_t>
float_t machine_eps()
{
union
{
float_t f;
int_t i;
} one, one_plus, little, last_little;

one.f = 1.0;
little.f = 1.0;
last_little.f = little.f;

while(true)
{
one_plus.f = one.f;
one_plus.f += little.f;

if( one.i != one_plus.i )
{
last_little.f = little.f;
little.f /= 2.0;
}
else
{
return last_little.f;
}
}
}

int main()
{
std::cout << "machine epsilon:\n";
std::cout << "float: " << std::setprecision(18)
<< machine_eps<float, uint32_t>() << std::endl;
std::cout << "double: " << std::setprecision(18)
<< machine_eps<double, uint64_t>() << std::endl;
}

/home/tomek/roboczy/test$ g++ -o test test.cpp && ./test
machine epsilon:
float: 1.1920928955078125e-07
double: 2.22044604925031308e-16

ale to oczywiście tylko aproksymacja
--
Tomek
http://www.ttmath.org
slawek
2012-11-05 23:16:22 UTC
Permalink
Post by Tomasz Sowa
ale to oczywiście tylko aproksymacja
Popatrz na to w ten sposób - manipulujesz bitami, robisz unie, używasz
szablonów. I otrzymujesz wynik 2.22E-16.

A wystarczy napisać cout << (1.0 + 1.5E-16 > 1.0) << endl; i ew. sprawdzić,
co da cout << (1.5E-16 < 2.2E-16) << endl; .
Tomasz Sowa
2012-11-05 23:19:10 UTC
Permalink
Post by slawek
Popatrz na to w ten sposób - manipulujesz bitami, robisz unie, używasz
szablonów. I otrzymujesz wynik 2.22E-16.
A wystarczy napisać cout << (1.0 + 1.5E-16 > 1.0) << endl; i ew. sprawdzić,
co da cout << (1.5E-16 < 2.2E-16) << endl; .
No właśnie nie wystarczy, unie zrobiłem specjalnie żeby obliczenie
dodawania zrobić odpowiednio w 32 bitach (float) i 64 bitach (double). W
twoim przypadku obliczenia będą przeprowadzone w 80 bitach lub więcej
(zależnie od opcji kompilacji).
--
Tomek
http://www.ttmath.org
slawek
2012-11-06 09:46:22 UTC
Permalink
Użytkownik "Tomasz Sowa" napisał w wiadomości grup
Post by Tomasz Sowa
No właśnie nie wystarczy, unie zrobiłem specjalnie żeby obliczenie
dodawania zrobić odpowiednio w 32 bitach (float) i 64 bitach (double). W
twoim przypadku obliczenia będą przeprowadzone w 80 bitach lub więcej
(zależnie od opcji kompilacji).
Ok, ale podążając za twoim pomysłem należałoby stwierdzić, że jakiekolwiek
porównania a > b należy usunąć z programów i zastąpić je porównaniami (int)a
Post by Tomasz Sowa
(int)b .
Czyli - zamiast problemu "DBL_EPSILON jest podany z 50% błędem" - mamy
problem "arytmetyka liczb double jest źle zaimplementowana". Miałem napisać
"ROTFL", ale jak się głębiej zastanowić - nie ma się z czego śmiać.
AK
2012-11-06 10:48:04 UTC
Permalink
Post by Tomasz Sowa
No właśnie nie wystarczy, unie zrobiłem specjalnie żeby obliczenie
dodawania zrobić odpowiednio w 32 bitach (float) i 64 bitach (double). W
twoim przypadku obliczenia będą przeprowadzone w 80 bitach lub więcej
(zależnie od opcji kompilacji).
Ok, ale podążając za twoim pomysłem należałoby stwierdzić, że jakiekolwiek porównania a > b należy
usunąć z programów i zastąpić je porównaniami (int)a
Post by Tomasz Sowa
(int)b .
Nie buraku i (jak widac) niedouku.
Takie porownania _zawsze_ robi sie np. w ten sposob.

int fp
a > b (a - b) > EPS
a < b (a - b) > -EPS
a >= b (a - b) >= -EPS
a <= b (a - b) <= EPS
a == b fabs(a - b) <= EPS
a != b fabs(a - b) > EPS

Wszedzie. W numeryce, nawet w bankowosci (nie wszedzie jest/byl decimal)
slowem wszedzie gdzie wystepuja dzialania na fp

W dodatku to EPS winno byc o wiele wieksze od DBL_EPSILON
i innych maszynowych bebechow (czesto jest to zreszta EPS wzgledne).
Owszem, masochistow sie nie uleczy wiec mozna im zezwolic
na uzycie DBL_EPSILON jako EPS, tyle te to podwojone (2.22..) z
naglowkow C z Pythona i Matlaba. Sam sobie odpowiedz dlaczego.
Przy pojedynczym pojawiaja sie "male klopoty".

AK
AK
2012-11-06 11:05:08 UTC
Permalink
Post by AK
a < b (a - b) > -EPS
winno byc:
a < b (a - b) < -EPS

AK
Roman W
2012-11-06 12:31:20 UTC
Permalink
Post by AK
Nie buraku i (jak widac) niedouku.
Takie porownania _zawsze_ robi sie np. w ten sposob.
int fp
a > b (a - b) > EPS
a < b (a - b) > -EPS
a >= b (a - b) >= -EPS
a <= b (a - b) <= EPS
a == b fabs(a - b) <= EPS
a != b fabs(a - b) > EPS
Nie jestem przekonany do tego, ze tak sie powinno robic ZAWSZE. Jezeli mam kod:

if (a >= 0) {
b = sqrt(a);
} else {
// zglos blad ze a ujemne
}

to zastepowanie "a >= 0" przez "a >= EPS" nie ma sensu.

RW
Michoo
2012-11-06 13:36:50 UTC
Permalink
if (a>= 0) {
Ale to jest porównanie ze stałą a nie porównanie dwóch liczb.
--
Pozdrawiam
Michoo
AK
2012-11-06 14:02:10 UTC
Permalink
Post by Michoo
if (a>= 0) {
Ale to jest porównanie ze stałą a nie porównanie dwóch liczb.
Nie ma znaczenia.
'a' nie jest stala.
_Zawsze_ (no... z naprawde minimalnymi wyjatkami potwierdzajacymi regule:) trzeba tak uzywac fp.

PS: K..de, ten temat chyba nigdy zniknie ;)
Pisze o tym "problemie": na wszelkich usenetach od 30 lat :)))

PS1: nawet dwie stale trzeba tak porownywac :)
Dlaczego ? A bo:
3.14159256dalej_nie_pamietam0000000000033333 == 3.14159256dalej_nie_pamietam0000000000077777
da true

AK
Roman W
2012-11-06 14:57:03 UTC
Permalink
if (a>= 0) {
Ale to jest por�wnanie ze sta�� a nie por�wnanie dw�ch liczb.
Porownanie "a >= b" jest rownowazne porownaniu "a - b >= 0".

RW
Michoo
2012-11-06 15:20:26 UTC
Permalink
if (a>= 0) {
Ale to jest por�wnanie ze sta�� a nie por�wnanie dw�ch liczb.
Porownanie "a>= b" jest rownowazne porownaniu "a - b>= 0".
Na komputerze nie ;)
unsigned int a=1,b=2;

Zero jest przecież dość szczególną wartością i jeżeli a jest mniejsze od
0 o epislon to czasami traktujemy je jako 0 dopiero po przemnożeniu *-1,
albo przypisaniu "wprost" zera.
--
Pozdrawiam
Michoo
Roman W
2012-11-06 16:31:18 UTC
Permalink
Post by Michoo
if (a>= 0) {
Ale to jest por�wnanie ze sta�� a nie por�wnanie dw�ch liczb.
Porownanie "a>= b" jest rownowazne porownaniu "a - b>= 0".
Na komputerze nie ;)
unsigned int a=1,b=2;
Chodzilo mi o double. Jezeli double a, b >= 0, to a - b tez jest reprezentowana (byc moze z bledem) przez double.

RW
AK
2012-11-06 13:55:59 UTC
Permalink
Post by Roman W
if (a >= 0) {
b = sqrt(a);
} else {
// zglos blad ze a ujemne
}
to zastepowanie "a >= 0" przez "a >= EPS" nie ma sensu.
Nie a >= EPS ale: a >= -EPS
Ma sens.

PS: Nigdy nie dostales z banku ponaglenia, ze masz natychmiast doplacic -0.00 zl ?
PS1: tak sie zdarzylo przed wielu wielu laty, ze uparte uzywanie przeze mie gdzie sie da w/w
konstrukcji skutkowalo tym, ze takie ponaglenia w systemie "defBank" pojawialy sie rzadko...

AK
AK
2012-11-06 14:35:49 UTC
Permalink
Post by AK
Ma sens.
Gwoli wyjasnienia:
Wez(cie) pod uwage, ze oczywiscie pisze dosc prowokacyjnie i dlatego "zaostrzam"
stanowisko niczym f.Diraca.
W "zyciu" problemy z uzywaniem fp sa bardziej "gaussowskie" czyli mozna niekiedy
(a zcasami nawet czesto) uzywac zwyklych porownan, ale trzeba to czynic z glowa
swiadoma jak "smakuja" fp i zawsze sie zastanowic czym moze skutkowac
_w konkretnym przypadku_ takie "ostre" porownanie.
Na luzie:
Przyklad trywalny: Jesli taka czaskowa x = -0.00000000001 ma trafic jako
suma_wydatkow += x to jak najbardziej _nie wolno_ tegox traktowac jak 0.0,
ale jesli ta wynikowa suma_wydatkow == -0.00003 ma skutkowac blokada konta
i wpisaniem w rejest dlugow to.. powinno sie takiego programiste zamknac w celi lacznie
z "dluznikiem" :) Wyrok wykona sie sam..

AK
slawek
2012-11-06 20:07:34 UTC
Permalink
Post by AK
Wez(cie) pod uwage, ze oczywiscie pisze dosc prowokacyjnie i dlatego "zaostrzam"
stanowisko niczym f.Diraca.
To nie jest funkcja.
Post by AK
Przyklad trywalny: Jesli taka czaskowa x = -0.00000000001 ma trafic jako
suma_wydatkow += x to jak najbardziej _nie wolno_ tegox traktowac jak 0.0,
ale jesli ta wynikowa suma_wydatkow == -0.00003 ma skutkowac blokada konta
i wpisaniem w rejest dlugow to.. powinno sie takiego programiste zamknac w celi lacznie
Poczytaj do czego służą liczby BCD - przyda się tobie i twojemu bankowi.
Michoo
2012-11-06 20:26:59 UTC
Permalink
Post by slawek
Poczytaj do czego służą liczby BCD -
No do czego? Głównie do tego, ze można je wrzucić w prosty sposób na
różne wyświetlacze n-segmentowe. Ale elektronika od takich tworów też
prawie całkiem odeszła dawno temu na rzecz wyświetlaczy z wbudowanym
sterownikiem do którego można "po ludzku" pisać.
Post by slawek
przyda się tobie i twojemu bankowi.
Walnąłeś jak dzik w sosnę. Tu nie potrzeba BCD (chociaż oczywiście można
je użyć) a jedynie reprezentacji fixed point.
--
Pozdrawiam
Michoo
slawek
2012-11-06 20:50:22 UTC
Permalink
Post by Michoo
Walnąłeś jak dzik w sosnę. Tu nie potrzeba BCD (chociaż oczywiście można
je użyć) a jedynie reprezentacji fixed point.
Skoro można - to dlaczego ich nie używać? Zwykłe fixed point z base 2 będą
kłopotliwe. BCD ułatwią sztywne trzymanie się głupawek w rodzaju:
"zaokrąglamy w górę do pełnych 10 gr". I oczywiście CPU ma pełen zestaw
instrukcji obsługujących BCD. Ale oczywiście - można też po prostu zapisywać
wszystko jako zwykły tekst (XML ?!)
AK
2012-11-06 21:33:08 UTC
Permalink
Post by slawek
Poczytaj do czego służą liczby BCD - przyda się tobie i twojemu bankowi.
Oj buraczku niedouczony :) /wciaz czekam az przeprosisz Bartka/.
_Co_ niby gwarantuje ci system dzesietny miast dwojkowego ?
Nawet przy tak trywialnnym podzieleniu 1/3.0 ?
Nie bedzie zadnego "obciecia" ?
Jak myslisz ? Moze w tym przypadu zwykle standardowe fp double bedzie lepsze ?
Moze nawet 32-bitowe float bedzie lepsze (dokladniejesze) od twych wybajanych decimali ?
Hę ?

AK

bartekltg
2012-11-06 14:54:28 UTC
Permalink
Post by AK
Post by Roman W
if (a >= 0) {
b = sqrt(a);
} else {
// zglos blad ze a ujemne
}
to zastepowanie "a >= 0" przez "a >= EPS" nie ma sensu.
Nie a >= EPS ale: a >= -EPS
Ma sens.
PS: Nigdy nie dostales z banku ponaglenia, ze masz natychmiast doplacic -0.00 zl ?
Ale ujemne zero ani ujemna liczba float nie spełnia x>0!
Może problem był w tym, że ten warunek sprawdzano zbyt
wcześnie, potem robiąc obliczenia, które gubiły dokładność.


Ale ja nie o tym chciałem...
Post by AK
a == b fabs(a - b) <= EPS
a != b fabs(a - b) > EPS
To trochę bez sensu.

Raz a i b są rządu 10^50, za drugim razem
rzędu 10^-30.
I obie różnice mam badać tym samym epsylonem?
Ale dla pierwszej pary powinien być w okolicy
10^36, a w drugiej 10^-44 :)

Chyba miałeś na myśli coś w rodzaju

a == b fabs(a - b) <= EPS * (a+b)
a != b fabs(a - b) > EPS * (a+b)


pzdr
bartekltg
AK
2012-11-06 15:48:28 UTC
Permalink
Post by bartekltg
Ale ujemne zero ani ujemna liczba float nie spełnia x>0!
Wiem, widzialem to. Secjalnie zostawilem.
Po prostu trzeba zrobic sqrt(max(0.0, a))
Czyli ? Jak zwykle: Myslec i "byc swiadom".
Nie ma idealnego "schematu dzialania" dla fp.
Post by bartekltg
Może problem był w tym, że ten warunek sprawdzano zbyt
wcześnie, potem robiąc obliczenia, które gubiły dokładność.
Ale ja nie o tym chciałem...
Post by AK
a == b fabs(a - b) <= EPS
a != b fabs(a - b) > EPS
To trochę bez sensu.
Raz a i b są rządu 10^50, za drugim razem
rzędu 10^-30.
I obie różnice mam badać tym samym epsylonem?
Ale dla pierwszej pary powinien być w okolicy
10^36, a w drugiej 10^-44 :)
Pisalem jzu tez ze bardzo czesto w numeryce uzywa sie EPS wzglednego.
Jak juz chyba kiedys tu pisalem "prawdziwa sztuka" to niekiedy wlasnie
dobor EPS.
Czasami sam dobor kroku w metodach optymalizacyjnuych
to prawdziwa sztuka i czesto nietrywailnuy algorytm..
Zalezy on a jakze on zmian wynikow czaskowych czyli posrednio od EPS.

W primitywnych obliczeniach jednak jak najbardziej EPS moze byc staly.
Zalezny po prostu od dlugosci mantysy.
Post by bartekltg
Chyba miałeś na myśli coś w rodzaju
a == b fabs(a - b) <= EPS * (a+b)
a != b fabs(a - b) > EPS * (a+b)
Rowniez. Pisalem o wzglednosci EPSa ale przeciez chodzi o zasade
wiec nie chce zaciemniac niekiedy naprawde nietrywialna "praktyka".
Szczegolnie np. w optymalizacji "plaskich funkcji" pojawia sie
problem "kiedy przestac" i/lub kiedy wydluzyc krok.
To neikiedy wrecz decydujaco wplywa na sprawnosc, dokladnosc
czy pewnosc algorytmu.
Tu sam EPS nie wystarczy
Tu np. trzeba wpierw zrobic jakis skalowanie "teoretyczne"
we wzorze funkcji, aby otrzymywane wyniki (wartosci) nie maily
zakresu 0.00000...0001 ale przyslowiowy 1.000
Nie wystarczu skalowanie "mechaniczne" (pomozenie wyniku)
bo juz jest po stracie cyfr znaczacych mantysy.
Itp itd i tak dalej. cala poddziedzina numeryki.

PS: jeszcze pamietam, ze np w metodach optymaliacji gradientowych
(np po lbie mi chodza do dzis nazwy metod Powella, Fletchera,
Wollfa-Broydena-Davidona itd itp) poprawa kiedunku gradientu to
nie byla tylko teoria.
Czasami sprawdzaly sie malo deterministyczne dzialania zawezajace stozek
dopusczalny gradientu, czasami byly to jakies heurystyki a niekeidy pomocne
byly nawet tak z pozoru oblesne "techniki" jak kilka rzutow kostka w
MonreCarlo w poblizu "miejsca chwilowego postoju".
(ze o rownanich rozniczkowych juz nie wspomne, tam EPS i krook to wprost sedno
choc tu sie "nie znam" :)
Czy to sie wiaze z EPS ? Posrednio jak najbardziej.
Ciagle sie sprawdzalo jakis roznice, kroki itp (sorry malo co pamietam
bylo to 30 lat temy tak tak, jeszcze na Odrze :)

Zreszta Wy "numerycy" sami to wiecie :)
Pisze raczej do mniej swiadomych.

AK
slawek
2012-11-06 20:13:02 UTC
Permalink
Post by AK
PS: jeszcze pamietam, ze np w metodach optymaliacji gradientowych
Zdecydowanie przereklamowanych.
Post by AK
MonreCarlo w poblizu "miejsca chwilowego postoju".
Monte Carlo. I tych metod Monte Carlo też jest więcej niż jedna.
Post by AK
Ciagle sie sprawdzalo jakis roznice, kroki itp (sorry malo co pamietam
bylo to 30 lat temy tak tak, jeszcze na Odrze :)
30 lat temu był już i CDC6000 (MINUIT) i PDP-11. Ale oczywiście mogłeś się z
tym sprzętem nie stykać.
Post by AK
Pisze raczej do mniej swiadomych.
Bo ci łykają to co piszesz jak młode pelikany?
Roman W
2012-11-06 15:03:15 UTC
Permalink
Post by AK
Post by Roman W
if (a >= 0) {
b = sqrt(a);
} else {
// zglos blad ze a ujemne
}
to zastepowanie "a >= 0" przez "a >= EPS" nie ma sensu.
Nie a >= EPS ale: a >= -EPS
Ma sens.
Nie ma, bo dla a == -1E-18 wyprodukuje NaN.
Post by AK
PS: Nigdy nie dostales z banku ponaglenia, ze masz natychmiast doplacic -0.00 zl ?
A co to ma do rzeczy? Swiat sie nie konczy na sofcie do obrabiania cyferek
na kontach.

RW
AK
2012-11-06 15:56:27 UTC
Permalink
Post by AK
PS: Nigdy nie dostales z banku ponaglenia, ze masz natychmiast doplacic -0.00 zl ?
A co to ma do rzeczy? Swiat sie nie konczy na sofcie do obrabiania cyferek na kontach.
Ano nie konczy.
Dajmy na to jest sobie obrabiarka numeryczna i program robiacy korekte noza

double y = obliczenia_geometrii()
ny = skoryguj_polozenie noza(ny, y)

No i teraz sobie wyobraz ze dzialasz "ostro" a nie z EPS.
Niezle wygladala by powierzchnia tak obrobionego przedmiotu (jak pomarancza :)
a chyba glowica by sie rozleciala z ciglych drgan.
Gdy zadzialamy z EPS (a rzadko kiedy obrabia sie zdokladnosci wieksza od EPS=0.01 mm
to wszysko sie uskopoi.

PS: Tak tak. W mechanice i CAD/CAM/CAE tez dlugo "siedzialem".

AK
Roman W
2012-11-06 16:32:06 UTC
Permalink
Post by AK
Post by AK
PS: Nigdy nie dostales z banku ponaglenia, ze masz natychmiast doplacic -0.00 zl ?
A co to ma do rzeczy? Swiat sie nie konczy na sofcie do obrabiania cyferek na kontach.
Ano nie konczy.
Dajmy na to jest sobie obrabiarka numeryczna i program robiacy korekte noza
double y = obliczenia_geometrii()
ny = skoryguj_polozenie noza(ny, y)
No i teraz sobie wyobraz ze dzialasz "ostro" a nie z EPS.
Niezle wygladala by powierzchnia tak obrobionego przedmiotu (jak pomarancza :)
a chyba glowica by sie rozleciala z ciglych drgan.
Gdy zadzialamy z EPS (a rzadko kiedy obrabia sie zdokladnosci wieksza od EPS=0.01 mm
to wszysko sie uskopoi.
Zgoda. Ale nadal twierdze, ze wyciaganie pierwiastka z ujemnej liczby to zly pomysl.

RW
AK
2012-11-06 19:49:06 UTC
Permalink
Post by Roman W
Zgoda. Ale nadal twierdze, ze wyciaganie pierwiastka z ujemnej liczby to zly pomysl.
Zgoda.
1. Nigdy nie twierdzilem inaczej.
2. Pisalem, ze _zawsze_ tzrzeba myslec, a nie kierowac sie wylacznie/balwochwalczo schematami (moim
tez).
3. Widzialem ten minus od poczatku, ale zostawilem bo 6.
4. Twoje kontrargumenty z NaN (i ew INF) sa nietrafione bo tycza zarowno porownan z EPS jak i bez.
Poza tym nie wszedzie w ogole pojawi sie NaN/INF.
5. Arytmetyka interwalowa jest super, ale rzadko podwojny koszt jest uzasadniony.
Nie zawsze jest potrzebne az tak dokladne/deterministyczne/"doswiadczalne oszacowanie bledu
wynikow jesli z "natury" (teoretycznej) algorytm zapewnia tabilnosc numeyczna/zbieznosc i/lub
"znoszenie sie" bledow.
6. Jestem wredny i mimo starosci w dyskusjach wciaz jeszcze dosc przebiegly i prowokacyjny.
Potrafie sie tez spokojnie "podlozyc", bom na tyle "wewnetrznie" zarozumialy (patrz: pewny
siebie:),
ze olewam udowadnianie narcystyczne czegokolwiek komukolwiek w sensie lemingowatego paradygmatu:
"JA uber alles" (ale prawde kocham jak zycie. No i _tworcze_ dyskusje tez:)
7.Marza mi sie na tej grupie "wojny algorytmiczne" i rozmowy/wojny o prawdziwych _merytorycznych_
problemach i mimo ze nie pamietam juz wzrorow na pierwiastki kwadratowe to chetnie podjalbym i
dzis
rekawicę hm.. np. w numerycznuym znajdowaniu pierwiastkow wielomianu zespolonego.
Nie ma _najmniejszego znaczenia_ czy bym przegral lub wygral.
Wazne ze _znow_ bym sie (i mam nadzieje tez inni tez) czegos nauczyl/wyniosl i na chwile
zaspokoil
starczy juz nalog :).
(nie nie!. Algorytm chyba Legurrea wcale _w praktyce_ nie byl najlepszy.. ani najszybszy ani
najstabilniejszy/"najzbiezniejszy". o ! tam to dopiero byla zabawa z H-ami i EPS-ami wszelkimi:).
8. Wiem ze to marzenie "scietej glowy", a grupa znow utonie w "assemblerowych problemach" firow
i w chamstwie/prymitywizmie tudziez DBL_EPS-ilonowatosci "niebieskich" slawkow


AK
bartekltg
2012-11-06 20:45:06 UTC
Permalink
Post by AK
7.Marza mi sie na tej grupie "wojny algorytmiczne" i rozmowy/wojny o
prawdziwych _merytorycznych_
problemach i mimo ze nie pamietam juz wzrorow na pierwiastki
kwadratowe to chetnie podjalbym i dzis
rekawicę hm.. np. w numerycznuym znajdowaniu pierwiastkow wielomianu zespolonego.
Nie ma _najmniejszego znaczenia_ czy bym przegral lub wygral.
Wazne ze _znow_ bym sie (i mam nadzieje tez inni tez) czegos
nauczyl/wyniosl i na chwile zaspokoil
starczy juz nalog :).
Bywają. Raz na ruski rok, ale są. Ostatnio np były zmagania z pewnym
problemem, któy okazał się simplexem, był wątek o sortowaniu,
gdzie leciały jakieś wyniki. Jak coś ceikawetgo zaproponujesz,
pewnie się ktoś dołączy.

A jak nie, za dwa tygodnie potyczki algorytmiczne;)
Post by AK
(nie nie!. Algorytm chyba Legurrea wcale _w praktyce_ nie byl
najlepszy.. ani najszybszy ani
najstabilniejszy/"najzbiezniejszy". o ! tam to dopiero byla zabawa z
H-ami i EPS-ami wszelkimi:).
8. Wiem ze to marzenie "scietej glowy", a grupa znow utonie w
"assemblerowych problemach" firow
i w chamstwie/prymitywizmie tudziez DBL_EPS-ilonowatosci
"niebieskich" slawkow
Jakoś sobie z nimi radzimy.

pzdr
bartekltg
slawek
2012-11-06 20:22:46 UTC
Permalink
Post by Roman W
Zgoda. Ale nadal twierdze, ze wyciaganie pierwiastka z ujemnej liczby to zly pomysl.
Dobry pomysł panocku, ino nijak nie idzie rozeznać, który potem wybrać.
slawek
2012-11-06 20:17:26 UTC
Permalink
Post by AK
Niezle wygladala by powierzchnia tak obrobionego przedmiotu (jak pomarancza :)
a chyba glowica by sie rozleciala z ciglych drgan.
O, ciekawe, ciekawe... widać że "expert" potrafi obrabiać powierzchnie
idealnie na glacę i to bez nadtapiania.
slawek
2012-11-06 20:06:01 UTC
Permalink
Post by AK
PS: Nigdy nie dostales z banku ponaglenia, ze masz natychmiast doplacic -0.00 zl ?
PS1: tak sie zdarzylo przed wielu wielu laty, ze uparte uzywanie przeze
mie gdzie sie da w/w
konstrukcji skutkowalo tym, ze takie ponaglenia w systemie
"defBank" pojawialy sie rzadko...
Zupełnie szczerze zapytam - to w bankach (polskich?) nie używa się BCD -
tylko zwykłych "floatsów"?!
Roman W
2012-11-06 20:31:57 UTC
Permalink
Post by slawek
Zupełnie szczerze zapytam - to w bankach (polskich?) nie używa się BCD -
tylko zwykłych "floatsów"?!
Zalezy do czego. Do wyceny derywatow, czy nawet rozliczania ich platnosci, wszyscy normalni ludzie uzywaja double. Bo hedge fund sie nie bedzie czepial, ze dostali £400,000.02 zamiast £400,000.01 przelewem. Natomiast do prowadzenia konta pana Zdzisia pewnie uzywa sie BCD.

RW
AK
2012-11-06 21:15:48 UTC
Permalink
Post by AK
konstrukcji skutkowalo tym, ze takie ponaglenia w systemie "defBank" pojawialy sie
rzadko...
Zupełnie szczerze zapytam - to w bankach (polskich?) nie używa się BCD - tylko zwykłych
"floatsów"?!
A BCD buraku cokolwiek ci gwarantuja ?
Czy _cokolwiek_ gwaranutuje ci dokladne obliczenia w/g nietrywialnych wzorow
gdzie z natury rzeczy mantysa jest ograniczona (chocby niala i 1000) cyfr znaczacych?
Nie gwarantuja tych rzeczy ani bcd ani fixed points ani fp ani nawet decimal.
Owszem np. zwlaszcza decimal baaardzo pomagaja (bo pozwalaja "trzymac"
dokladna reprezentacje dziesietna i wykonywac trywialne dzialania bez bledow),
ale kilka potegowan, z jeden logarytm, kilka malych dzielonek i juz masz kaszane
bo jakis tam bit/digit jednak moze obciac.

PS: Tak sie sklada ze w czasach gdy powstawal Assecowy defBank
to byl sobie skromny Borland TC1.0 (jeszcze 16 bitowy ) w ktorym byl on pisany.
(duze uklony i dzis po latach dla autorow), a taki MS C to byl zupelnie w powijakach
(masa bledow).
(wiesz o tym palancie ze MS mial wtedy jeszze swoj wcale niezgodny z IEEE format fp ?
wiesz ze takie koprocesory Weitek (kiedys potega) tez mialy "swoje" rozwiazania ?)
Cala arytmetyka/"hipoteka" w defBank byla na zwyklym double bo _nie bylo nic innego
do uzycia_. Mysle ze do dzis jest wlasnie na tych samych double (ot zaszlosci).
Jak widac Asseco nie upadlo jakos :) i defBank tez z tego powodu sie nie posypal.
Bo buraku fp trzeba naprawde i po prostu _umiec uzywac_.
Gdy sie to umie i czuje to mozna ich uzywac nawet jako dokladnych integers /80bits
to zawsze wiecej niz wtedy 16/32/ a dzis 64 :)
Ja sie tego nauczylem na wysmiewanej przez ciebie Odrze i mimo ze zaczalem nawet pisac
nieco (drobiazgi) w Planie to formatu Odrowych fp ani wtedy ani dzis nie znam
(mimo ze "na Odrze" siedzialem cale studia) bo mi to _nigdy do niczego nie bylo potrzebne_.
No ale ja sie wychowalem na ksiazce Macieja Sysły "Algorytmy optymalizacjiw jezyku Algol"
gdzie juz w pierwszym algorytmie (simplex) stalo jak byk cos w rodzaju:
if abs(a-b) <= EPS then return
i nie byl zadnego magicznego DBL_EPSILONA

AK
kenobi
2012-11-06 21:30:10 UTC
Permalink
Post by AK
A BCD buraku cokolwiek ci gwarantuja ?
żeby sparafrazowac AL 'kolega to chyba powinien jednak siedziec w zoo'
slawek
2012-11-06 20:03:04 UTC
Permalink
Post by AK
Wszedzie. W numeryce, nawet w bankowosci (nie wszedzie jest/byl decimal)
slowem wszedzie gdzie wystepuja dzialania na fp [ ciach trywialne
zastosowanie fabs i eps ]
1. Każda dobra implementacja "floatsów" gwarantuje, że jeżeli a > b to nie
jest b > a, oraz jeżeli a == b to nie zachodzą ostre nierówności. Dlatego
porównywanie jest (powinno być) bezpieczne.

2. Nie jest dobra implementacja, w której a = b nie gwarantuje potem a ==
b. Oczywiście to samo dla a = b, c = b, sprawdzamy a == c . Zła
implementacja - i nawet "protezy" w rodzaju "epsilonowania" każdego
porównania liczb rzeczywistych niewiele pomagają.
Michoo
2012-11-06 20:36:17 UTC
Permalink
2. Nie jest dobra implementacja, w której a = b nie gwarantuje potem a
== b. Oczywiście to samo dla a = b, c = b, sprawdzamy a == c . Zła
implementacja - i nawet "protezy" w rodzaju "epsilonowania" każdego
porównania liczb rzeczywistych niewiele pomagają.
Udajesz, że nie rozumiesz problemu. ;)

Jeżeli a==b i c==b to a==c. Ale jeżeli a, b i c to wyniki trzech różnych
obliczeń których wartością jest ta sama liczba rzeczywista a niektóre
wyniki pośrednie nie są reprezentowane _dokładnie_ w użytym typie danych
otrzymujesz trzy wartości różne binarnie, ale równe logicznie. Od tego
jest "epsilonowanie", żeby w toku obliczeń też były traktowane jako równe.
--
Pozdrawiam
Michoo
slawek
2012-11-06 21:01:39 UTC
Permalink
Post by Michoo
otrzymujesz trzy wartości różne binarnie, ale równe logicznie. Od tego
jest "epsilonowanie", żeby w toku obliczeń też były traktowane jako równe.
Masz rację.

Jednak ta racja odnosi się do "interpretacji logicznej" (robione z
dokładnością 1%, trzy pomiary 4.02, 4.01, 4.04 są w granicach tolerancji
identyczne).

Mi chodziło o interpretację "formalną" - tj. mam dwie liczby double, jedna
a, druga b, wiem że nie mogą zachodzi jednocześnie ani dwie, ani trzy, z
trzech relacji a > b, a == b, a < b.

Mogę np. sortować "po double". Wiem, że jeżeli a == b w jakimś miejscu
programu oraz gdy c = a, d = b to c == d itd.

Kwestia interpretacji nie jest istotna na tym poziomie abstrakcji. Po prostu
język (C/Algol/cokolwiek) ma operację porównywania "floatsów" - więc
porównywanie "floatsów" jest dobrze określone w danym języku. Wolno je robić
i musi mieć jednoznacznie określone rezultaty - nawet jeżeli nie ma sensu
(jak np. porównywanie liczby chomików z temperaturą w lipcu).
AK
2012-11-06 21:18:27 UTC
Permalink
otrzymujesz trzy wartości różne binarnie, ale równe logicznie. Od tego jest "epsilonowanie", żeby
w toku obliczeń też były traktowane jako równe.
Swietnie to ujales. Sedno.

AK
Michoo
2012-11-06 10:50:50 UTC
Permalink
Użytkownik "Tomasz Sowa" napisał w wiadomości grup
Post by Tomasz Sowa
No właśnie nie wystarczy, unie zrobiłem specjalnie żeby obliczenie
dodawania zrobić odpowiednio w 32 bitach (float) i 64 bitach (double). W
twoim przypadku obliczenia będą przeprowadzone w 80 bitach lub więcej
(zależnie od opcji kompilacji).
Ok, ale podążając za twoim pomysłem należałoby stwierdzić, że
jakiekolwiek porównania a > b należy usunąć z programów i zastąpić je
porównaniami (int)a > (int)b .
Czyli - zamiast problemu "DBL_EPSILON jest podany z 50% błędem"
NIE jest, nie trolluj. Już ci podawałem fragment standardu, w którym
wyraźnie stoi, że DBL_EPSILON zawiera dodatnią różnicę między 1.0 a
następną wartością reprezentowalną w typie double.
- mamy
problem "arytmetyka liczb double jest źle zaimplementowana".
Czy ty kiedyś siedziałeś gdzieś w pobliżu numeryki?

Jeżeli dokładność jest większa to nie jest to problem, chyba, że
programista naprawdę coś zepsuł. Precyzja w punktach wynosi 100%,
dlatego używa się ograniczeń worst-case. Nikt myślący nie zrobi w
typowym przypadku relacji równoważności[*] w oparciu o DBL_EPSILON -
zawsze to będzie jego wielokrotność.


P.S.
Skompiluj, uruchom, zrozum:

#include <cstdio>
double foo(double d){
return d;
}
main()
{
double d1=1.0;
double d2=1.5E-16;
printf("%.18lf %.18lf\n",d1+d2-1.0,foo(d1+d2)-1.0);
}

[*] Wynika to z tego, że każda operacja wprowadza przynajmniej błąd z
przedziału <0,DBL_EPSILON/2>, niektóre tak duży jak np
sqrt(DBL_EPSILON/2) - np. sqrt ;)
--
Pozdrawiam
Michoo
slawek
2012-11-06 20:39:17 UTC
Permalink
Post by Michoo
NIE jest, nie trolluj. Już ci podawałem fragment standardu, w którym
wyraźnie stoi, że DBL_EPSILON zawiera dodatnią różnicę między 1.0 a
następną wartością reprezentowalną w typie double.
No przecież piszę - że nie jest.

Tzn. że problem nie jest z DBL_EPSILON (jak myślałem na początku) - tylko z
zepsutą arytmetyką na double.
Post by Michoo
Jeżeli dokładność jest większa to nie jest to problem, chyba, że
Jest problem. Duży. Po prostu wyniki przestają być przewidywalne i
powtarzalne.

Wystarczy że ten sam program ktoś skompiluje trochę inaczej, ba, może to być
nawet ten sam kompilator ale w nieco nowszej wersji. Raz jest dobrze (bo
miałeś "trochę lepiej") - a potem nagle okaże się, że jednak jest źle (bo
tym razem nie chciało być "trochę lepiej").
Loading...