eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programmingBłędny epsilon - this is not a bug, this is ?Re: Błędny epsilon - this is not a bug, this is ?
  • Data: 2012-11-03 11:48:52
    Temat: Re: Błędny epsilon - this is not a bug, this is ?
    Od: Tomasz Sowa <t...@N...ttmath.org> szukaj wiadomości tego autora
    [ pokaż wszystkie nagłówki ]

    On 2012.11.01 11:15, slawek wrote:

    > 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)

    > 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?

    > Algorytm "fast"

    O(1) patrz poniżej

    > 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ść.

    > 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.

    > 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

Podziel się

Poleć ten post znajomemu poleć

Wydrukuj ten post drukuj


Następne wpisy z tego wątku

Najnowsze wątki z tej grupy


Najnowsze wątki

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: