RTV forum PL | NewsGroups PL

Precyzja liczb zmiennoprzecinkowych w VB6 - dlaczego wynik 31 nie równa się 31?

Porównywanie liczb, double float

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Precyzja liczb zmiennoprzecinkowych w VB6 - dlaczego wynik 31 nie równa się 31?

Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next

Pszemol
Guest

Thu Jun 13, 2019 1:36 pm   



<sczygiel@gmail.com> wrote in message
news:f37ce076-b7e3-4dfc-803c-12c1d09de65d@googlegroups.com...
Quote:
W dniu środa, 12 czerwca 2019 07:17:44 UTC-5 użytkownik Pszemol napisał:

Czy to jest normalne zachowanie się VB6?

Czy inne Visuale jak VC++ lub VC# też tak mają?

Koledzy juz powiedzieli co trzeba. Ja dodam ze jak ten kto ten program
pisal naprawde malo wie i jesli on dzialal wczesniej to tylko przypadkiem.

Jesli on, ten kontraktor jest z indii to albo zglos to jako ryzyko projekt
managerowi i zasugeruj zeby znalezli nieco kompetentniejszego albo od
teraz testujcie wszystko tak jakby to wam, nie przymierzajac, malpa
pisala.

Co do PM-a. Policz ile czasu na to poswieciles, udokumentuj buga i
zbieraj. Jak sie trafi kolejny taki kwiatek to zbieraj w kupke.
Nawet dobry PM nie unegocjuje wiele bez podkladki. A negocjacje nie
koniecznie musza sie toczyc z kontraktorem, moze to byc tez wewnetrzne
tarcie na zmiane na inna lige cenowa.
Podkladka czyni cuda.

Nie wiem jaką mają z nim umowę.
Ale ich wystawił do wiatru bo ostatnio jakąś dodatkową funkcję
chcieli dodać do programu i nie był zainteresowany aby przyjść
i pisać ten kod dalej... Gdy patrzę jak jest kod napisany to się nie dziwię.

Pszemol
Guest

Thu Jun 13, 2019 1:37 pm   



"Mateusz Viste" <mateusz@nie.pamietam> wrote in message
news:5d00f035$0$15194$426a74cc@news.free.fr...
Quote:
On Wed, 12 Jun 2019 07:17:45 -0500, Pszemol wrote:
Pisząc w Visual Basic 6 gostek porównywał rezultat konwersji CDbl()
stringu od którego odjął stałą numeryczną 1.8 do lokalnej zmiennej
double.

Prawdziwi programiści nie używają liczb zmiennoprzecinkowych.

Faktem jest, że gdy zmienne nie skaczą dynamicznie od e-15 do e+15 to
warto znaleźć zakres wariacji mierzonej zmiennej, oczekwianą dokładność
i zamiast na float operować na long integer * 10000 na przykład...

Quote:

Dzięki za linka, zapoznam się w wolnym czasie.

Pszemol
Guest

Thu Jun 13, 2019 1:39 pm   



"J.F." <jfox_xnospamx@poczta.onet.pl> wrote in message
news:5d00f430$0$17345$65785112@news.neostrada.pl...
Quote:
Użytkownik "Pszemol" napisał w wiadomości grup
dyskusyjnych:qdqqh6$n2f$1@dont-email.me...
Sub AlaMaKota(nieważne tutaj argumenty procedury)
Dim len as Double

len = CDbl("tekst wydłubany z RS232") - 1.8

If len <> CDbl("inny tekst wydłubany z RS232) Then
zgłoś błąd i kapitulujemy... kaput!
Else
lecimy z testami talej, wsio w pariadkie
Endif.

Pierwszy tekst z RS232 był 32.8, drugi 31. 32.8-1.8 = 31.
Powinno być wszystko ok, bo w matematyce 31 równe jest 31 Smile
Wynik porównania VB6 był 31 nie jest równe 31 i program
kapitulował...

Przyczyną błędu była różnica odejmowania wynosząca 15.1234e-15

Dlaczego konwersja CDbl stringu 31 lub 32.8 dodaje jakieś
śmieci do zmiennej double float na 15 miejscu po przecinku??
A może odejmowanie stałej 1.8 wprowadza ten błąd?
Czy to jest normalne zachowanie się VB6?

To nie jest problem VB, to jest problem przyjetego formatu liczb
rzeczywistych.
Albo problem programisty :-)

31 jest dokladne, 0.8 nie.
0.5 jest dokladne, 0.25 i 0.75 itd - ale wiekszosc liczb "dziesietnych po
przecinku" niestety nie.

Po prostu nie da sie zapisac 32.8 dokladnie.
Programista ma o tym wiedziec i sie zabezpieczyc :-)

Czy inne Visuale jak VC++ lub VC# też tak mają?

To jest problem procesora z FP IEEEcostam.

Teraz jak czytam co napisałeś to wydaje się to oczywiste.
Ale taki byłem szczęśliwy że wreszcie znalazłem buga i uruchomiłem
program że samamu mi się ta klapka w mózgu nie odklapiła - dzięki.

Dariusz Dorochowicz
Guest

Thu Jun 13, 2019 3:28 pm   



W dniu 2019-06-12 o 14:17, Pszemol pisze:
Quote:
Witam, spędziłem wczoraj sporo godzin w biurze na debugowaniu
kodu napisanego przez naszego kontraktora i w końcu znalazłem buga.
Przyczyną błędu była różnica odejmowania dwu liczb całkowitych
wynosząca 15.1234e-15 :-)

Ale może więcej szczegółów podam:

Pisząc w Visual Basic 6 gostek porównywał rezultat konwersji CDbl()
stringu od którego odjął stałą numeryczną 1.8 do lokalnej zmiennej double.

Czyli mamy kod:

Sub AlaMaKota(nieważne tutaj argumenty procedury)
Dim len as Double

len = CDbl("tekst wydłubany z RS232") - 1.8

If len <> CDbl("inny tekst wydłubany z RS232) Then
   zgłoś błąd i kapitulujemy... kaput!
Else
   lecimy z testami talej, wsio w pariadkie
Endif.

Pierwszy tekst z RS232 był 32.8, drugi 31. 32.8-1.8 = 31.
Powinno być wszystko ok, bo w matematyce 31 równe jest 31 Smile
Wynik porównania VB6 był 31 nie jest równe 31 i program
kapitulował...

Po zamienieniu testu "if double <> double then" na test
"if double - double < -0.001 Or double - double > 0.001 then"
program zaczął pracować normalnie.

Przyczyną błędu była różnica odejmowania wynosząca 15.1234e-15

Dlaczego konwersja CDbl stringu 31 lub 32.8 dodaje jakieś
śmieci do zmiennej double float na 15 miejscu po przecinku??
A może odejmowanie stałej 1.8 wprowadza ten błąd?

Czy to jest normalne zachowanie się VB6?

Czy inne Visuale jak VC++ lub VC# też tak mają?

Kiedy dawno temu (naprawdę dawno) pisałem/modyfikowałem program do pracy
dyplomowej to w pewnym momencie zaczął się wysypywać z błędem dzielenia
przez zero. Po dochodzeniu okazało się że pomimo jawnej deklaracji
double pewne konkretne obliczenia robił na real i w mianowniku pojawiało
się zero. Żadne jawne deklaracje i wymuszenia typu obliczeń tego nie
potrafiły zmienić, pomogła dopiero zmiana kompilatora. Sztuczne dodanie
obliczeń powodowało tylko przesunięcie momentu wywalenia się programu.
Podobne obliczenia w innym miejscu robił jak należy. A ten drugi
(właściwie to on był pierwszy tylko z pewnych powodów chciałem użyć
innego) nie miał w ogóle takich problemów.

Pozdrawiam

DD

AK
Guest

Sun Jun 16, 2019 7:19 pm   



On 2019-06-12 14:44, J.F. wrote:
Quote:
Użytkownik "Pszemol"  napisał w wiadomości grup

To nie jest problem VB, to jest problem przyjetego formatu liczb
rzeczywistych.

I tam. Nieprawda. W _kazdym_ systemie/formacie FP moze sie zdarzyc.

Quote:
Albo problem programisty Smile

_Wylacznie_ problem programisty.

Quote:
Po prostu nie da sie zapisac 32.8 dokladnie.
Programista ma o tym wiedziec i sie zabezpieczyc Smile

Prawda!

Quote:
Czy inne Visuale jak VC++ lub VC# też tak mają?

To jest problem procesora z FP IEEEcostam.

Wcale nie. To jest problem jak najbardziej ogolny.

Quote:
Akurat .net ma dodatkowe formaty (Decimal), w ktorych powinno to dzialac.
Tylko trzeba ie
Ale i tak bym dorzucil zabezpieczenie.

Racja! Sam Decimal tak naprawde przed niczym sam z siebie nie chroni.

Quote:
Problem promieniuje na bazy danych, gdzie mamy duzo kwot, a te grosze
tez nie sa dokladne Smile

Raaacja ! :)

AK

AK
Guest

Sun Jun 16, 2019 7:21 pm   



On 2019-06-12 17:27, J.F. wrote:

Quote:
Kto nie uczyl sie Fortranu, ten nie zna zycia Smile

O przepraszam ! Ja sie uczylem Agolu/Simuli!

PS: No dobra.. Fortranu też ;)

AK

AK
Guest

Sun Jun 16, 2019 7:40 pm   



On 2019-06-12 16:54, Cezary Grądys wrote:
Quote:
W dniu 12.06.2019 o 14:29, Mateusz Viste pisze:


Prawdziwi programiści nie używają liczb zmiennoprzecinkowych.

Obowiązkowa lektura na wieczór:
http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf


Nie ma co przesadzać, liczby zmiennoprzecinkowe po to powstały, żeby je
używać. Trzeba tylko porównywać je zakładając pewną dopuszczalną
tolerancję.

No dooobra.
Zamieszcze tu po raz 473 w ciagu 20 lat podstawową formułkę
(Ba! KANON!), bo przy takiej wiedzy "mlodego pokolenia" znow
zaczną nam przychodzic ponaglenia o pilną zapłatę 0.00PLN.

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

PS: Oczywiscie EPS moze miec rozna nature i wartosci zaleznie np.
od domeny (numeryka, finanse itp). Np. Moze byc bezwzgledne, ale
czesto bywa wzgledne, a w numeryce to juz w ogole...
Np. w optymalizacji moze byc dynamiczne (np zalezne nie tylko
od wartosci ale i innych cech funkcji, np gradientu) i sztuka
sama w sobie jest je dobierac/szacowac np w slabo zbieznych algorytmach
czy gdy np. funcja jest baaardzo stroma. No ale to juz zupelnie inna
"para kaloszy".

PS0: Oczywiscie w niektorych "higienicznych" przypadkach (np. szukanie
wartosci maksymalnej) dopuszczalne jest zwykłę >, ale to nie
łamie/przeczy w/w regułom.

AK

AK
Guest

Sun Jun 16, 2019 7:43 pm   



On 2019-06-13 15:37, Pszemol wrote:
Quote:
"Mateusz Viste" <mateusz@nie.pamietam> wrote in message
news:5d00f035$0$15194$426a74cc@news.free.fr...
On Wed, 12 Jun 2019 07:17:45 -0500, Pszemol wrote:
Pisząc w Visual Basic 6 gostek porównywał rezultat konwersji CDbl()
stringu od którego odjął stałą numeryczną 1.8 do lokalnej zmiennej
double.

Prawdziwi programiści nie używają liczb zmiennoprzecinkowych.

Faktem jest, że gdy zmienne nie skaczą dynamicznie od e-15 do e+15 to
warto znaleźć zakres wariacji mierzonej zmiennej, oczekwianą dokładność
i zamiast na float operować na long integer * 10000 na przykład...

1. ile masz takich przypadkow w zyciu (owszem, fraktale).
2. przy dzisiejszych koprocesorach ? Na pewno warto ?
/Kiedys zdecydowanie tak, wiec absolutnie podejscia nie potępiam/.

AK

Szyk Cech
Guest

Sun Jun 16, 2019 8:10 pm   



Quote:
Musialbym sobie przypomniec ... ale przy okazji Assemblera raczej nikt
nie poruszal takiego watku.

Pierwsze publikacje o Asemblerze x86 pomijały 386 i koprocesor.
W takiej "Asembler nie tylko dla orłów" Grzegorza Michałka
(Intersoftland 1997) jest opisany 386 (i 486) z koprocesorem. I co
prawda nie rozwodzi się tam nad dokładnością obliczeń, ale... Podaje
jako jeden z możliwych błędów/wyjątków: "Utrata precyzji"/"Błąd
precyzji" - bit 6 rejestru stanu koprocesora.

Quote:
Przy C predzej, ale to gdzies na pograniczu.

Tak czy owak nie powinno się pomijać kilku słów komentarza, podczas
omawiania typów zmiennoprzecinkowych, na temat potencjalnych problemów
przy ich stosowaniu.

Mateusz Viste
Guest

Mon Jun 17, 2019 7:21 am   



On Sun, 16 Jun 2019 21:43:50 +0200, AK wrote:
Quote:
On 2019-06-13 15:37, Pszemol wrote:
"Mateusz Viste" <mateusz@nie.pamietam> wrote in message
news:5d00f035$0$15194$426a74cc@news.free.fr...
On Wed, 12 Jun 2019 07:17:45 -0500, Pszemol wrote:
Pisząc w Visual Basic 6 gostek porównywał rezultat konwersji CDbl()
stringu od którego odjął stałą numeryczną 1.8 do lokalnej zmiennej
double.

Prawdziwi programiści nie używają liczb zmiennoprzecinkowych.

Faktem jest, że gdy zmienne nie skaczą dynamicznie od e-15 do e+15 to
warto znaleźć zakres wariacji mierzonej zmiennej, oczekwianą dokładność
i zamiast na float operować na long integer * 10000 na przykład...

1. ile masz takich przypadkow w zyciu (owszem, fraktale).
2. przy dzisiejszych koprocesorach ? Na pewno warto ?
/Kiedys zdecydowanie tak, wiec absolutnie podejscia nie potępiam/.

Koprocesory nie mają tu nic do rzeczy - na 386SX też dało się korzystać z
float, mimo braku FPU. Oczywiście kosztem wydajności, ale nie o tym
przecież mówimy.

Float/Double ze swojej natury nie zapewnia dokładności i dlatego to je
skreśla w większości zastosowań w których ludzie intuicyjnie z nich
korzystają (głównie: liczenie pieniędzy). Fakt - są sytuacje kiedy float
*może* być dobrym rozwiązaniem: fraktale, przetwarzanie grafiki lub
dźwięku i generalnie wszystko, co nie wymaga ścisłego wyniku. Ale to -
przynajmniej z mojego punktu widzenia - specjalistyczne wyjątki.

Mateusz

Piotr Wyderski
Guest

Mon Jun 17, 2019 7:39 am   



Mateusz Viste wrote:

Quote:
Prawdziwi programiści nie używają liczb zmiennoprzecinkowych.

Prawdziwi programiści nie używają liczb zmiennoprzecinkowych bezmyślnie.
A żeby to móc robić "zmyślnie" mają co najmniej półroczny zaawansowany
wykład z analizy numerycznej. Oczywiście zdarzają się i tacy, co byli
za mądrzy na studia i użeranie się z profesorami-debilami, dzięki czemu
m.in. Pszemol ma fun.

Pozdrawiam, Piotr

Piotr Wyderski
Guest

Mon Jun 17, 2019 7:43 am   



AK wrote:

Quote:
No dooobra.
Zamieszcze tu po raz 473 w ciagu 20 lat podstawową formułkę
(Ba! KANON!), bo przy takiej wiedzy "mlodego pokolenia" znow
zaczną nam przychodzic ponaglenia o pilną zapłatę 0.00PLN.

[ciach formułki]

I nie mówcie mi, że na macie NaNa, bo w każdej chwili mieć możecie!
(sprawdzić, czy nie ksiądz).

Pozdrawiam, Piotr

Piotr Wyderski
Guest

Mon Jun 17, 2019 7:48 am   



AK wrote:

Quote:
1. ile masz takich przypadkow w zyciu (owszem, fraktale).

Z okolic "numerków", to filtry Hogenauera chyba tylko. Tam przepełnienia
stałoprzecinkowe i ich wzajemna kompensacja
są podstawą całej sztuczki.

Pozdrawiam, Piotr

Mateusz Viste
Guest

Mon Jun 17, 2019 7:53 am   



On Mon, 17 Jun 2019 09:39:08 +0200, Piotr Wyderski wrote:
Quote:
Prawdziwi programiści nie używają liczb zmiennoprzecinkowych bezmyślnie.
A żeby to móc robić "zmyślnie" mają co najmniej półroczny zaawansowany
wykład z analizy numerycznej. Oczywiście zdarzają się i tacy, co byli za
mądrzy na studia i użeranie się z profesorami-debilami, dzięki czemu
m.in. Pszemol ma fun.

Wszystko się zgadza, z tym że wniosek "był na studiach = wie co robi"
jest co najmniej nietrafiony. De facto studia - przynajmniej w sektorze
IT - to nic więcej jak strata czasu. Nie gwarantują one ani wiedzy, ani
pomyślunku, a zarówno to pierwsze jak i drugie można bez problemu nabyć
poza murami uczelni.

Mateusz

Piotr Wyderski
Guest

Mon Jun 17, 2019 10:59 am   



Mateusz Viste wrote:

Quote:
Wszystko się zgadza, z tym że wniosek "był na studiach = wie co robi"
jest co najmniej nietrafiony. De facto studia - przynajmniej w sektorze
IT - to nic więcej jak strata czasu. Nie gwarantują one ani wiedzy, ani
pomyślunku, a zarówno to pierwsze jak i drugie można bez problemu nabyć
poza murami uczelni.

Studia w ogóle niczego nie gwarantują, bo nie od tego są. Mają tylko za
zadanie zmusić delikwenta do nauki rzeczy, których bez przymusu sam by
się nie nauczył. Między innymi właśnie "numerków". Rzetelny kurs analizy
numerycznej z realną opcją wylotu w przypadku niezaliczenia
nieco się różni od poczytania sobie ballady o floacie do podusi.
Dokładnie tak samo w przypadku algorytmiki i złożoności obliczeniowej. A
przynajmniej tak było w moich czasach.

Pozdrawiam, Piotr

Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next

elektroda NewsGroups Forum Index - Elektronika Polska - Precyzja liczb zmiennoprzecinkowych w VB6 - dlaczego wynik 31 nie równa się 31?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map