[Solved] Float hiba pénznél - test case needed

 ( dszakal | 2017. február 21., kedd - 11:58 )

Keresek olyan tesztesetet (C, C++, Java, Python vagy PHP preferred), ahol a floating point nehany muveletet utan mar a masodik tizedesjegynel rosszul kerekit (hibasan tarolt cent/penny). Igen, tudom hogy a penz mindig integer kell legyen, meg hogy PostgreSQL-ben van direkt Money adattipus pl. De kell a teszteset a hibas tervezesrol.

Elore is koszonom.

Update: olyan teszteset kell, ahol 2 tizedesjegyre kerekitve is hibas az eredmeny. 4. 5. tizedesjegynel elromlot en is tudok, meg talaltam is neten. Masodik tizedesjegyet mas kodjaban egyszer sikerult reprodukalnom aranylag keves muvelettel, es olyan kell.

Update 2: megvan


#include <stdio.h>
int main()
{
        float f = 90.1;
        int i;
        float origf = f;
        for (i = 1; i < 1000; ++i) {
                f = f + origf;
        }
        printf("Float is %lf\n", f);
        return 0;
}

Float is 90100.890625

Koszi Persicsb az otletet.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

0.02 + 0.18 = 0.199999999999999998
És ez nem helyes eredmény. Persze, ha két tizedesre kerekíted, akkor 0.2 lesz, ami jó eredmény elvileg.

Vagy add össze a 0.03-mat százszor egymás után, majd hasonlítsd össze az eredmény 3-mal. sum(I=0..99) 0.03 < 3

És ez nyelvfüggetlen, az IEEE-754 szabványban mindig is így lesz, a gépi számokkal való számolás nagyon nagy hibákra vezethet.

Ez a for ciklus adott otletet, koszi

Koszi, megvan, updating

A második tizedes jegy viszonylag egyszerű, nem?

(0.3-0.2) * 1000

Vagy valami hasonló.
--
blogom

nem:

#include

int main()
{
        float f = 90.1;
        // f *= 1000.0;
        printf("Float is %lf\n", f);
        return 0;
}

igy:
Float is 90.099998

kikommentelve:
Float is 90100.000000

Hm. Ezt nem a C fordító optimalizálja ki? Vagy a 90.099998 * 1000 az 901000?

--
blogom

Nagyon nagy hiba az indokolatlan float használat, ezt előbb-utóbb megtapasztalja mindenki aki a saját kárán szeret tanulni. :)

PHP-s példa ahol látszólag csődöt mond a józan ész: $ php -r 'var_dump(0.1 + 0.2 === 0.3); //false'

Ha már úgyis megoldódott: https://www.xkcd.com/217/

Amit viszont nem tudok elohozni: double-nel ilyen peldakod ami rossz mar a vegeredmenynel 2 tizedesjegyre kerekitve is. Valakinek van valami otlete?

A legnagyobb problemaja a lebegopontos abrazolasnak, hogy a lehetseges abrazolt szamok surubben helyezkednek el 0 korul, de brutalisan megritkulnak a 0-tol tavol.

Szoval a hozzaadsz egy kis szamot (e.g.: 1.0) mondjuk 10.0^20-hoz, akkor az eredmeny el fog cseszodni, meg double eseten is.

Bármi, ami exponenciálisan nő, elég sok lépés után elromlik. Pl. kamatos kamat számolás, vagy ami lényegében ugyanaz, az e közelítése (1+1/n)^n-nel, n=10^15...10^16 körül. Tesztesetgyűjtemény a paranoia a netliben, http://www.netlib.org/paranoia/index.html