Goto page 1, 2, 3, 4, 5, 6, 7 Next
Pszemol
Guest
Wed Jun 12, 2019 12:17 pm
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
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ą?
Mateusz Viste
Guest
Wed Jun 12, 2019 12:29 pm
On Wed, 12 Jun 2019 07:17:45 -0500, Pszemol wrote:
Quote:
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.
Obowiązkowa lektura na wieczór:
http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf
Mateusz
J.F.
Guest
Wed Jun 12, 2019 12:44 pm
Użytkownik "Pszemol" napisał w wiadomości grup
dyskusyjnych:qdqqh6$n2f$1@dont-email.me...
Quote:
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
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 :-)
Quote:
Czy inne Visuale jak VC++ lub VC# też tak mają?
To jest problem procesora z FP IEEEcostam.
Akurat .net ma dodatkowe formaty (Decimal), w ktorych powinno to
dzialac.
Tylko trzeba ie
Ale i tak bym dorzucil zabezpieczenie.
Problem promieniuje na bazy danych, gdzie mamy duzo kwot, a te grosze
tez nie sa dokladne :-)
J.
Zbych
Guest
Wed Jun 12, 2019 12:48 pm
W dniu 12.06.2019 o 14:17, Pszemol pisze:
Quote:
Dlaczego konwersja CDbl stringu 31 lub 32.8 dodaje jakieś
śmieci do zmiennej double float na 15 miejscu po przecinku??
Bo typy rzeczywiste mają dużą dynamikę kosztem dużego szumu
Irek.N.
Guest
Wed Jun 12, 2019 12:56 pm
Quote:
Bo typy rzeczywiste mają dużą dynamikę kosztem dużego szumu
Kurde, a ja myślałem, że to jitter.
Chociaż nie, jitter jest losowy, a tutaj mamy całkowitą powtarzalność,
coś jak problem z kwantami bardziej ;)
Miłego.
Irek.N.
JDX
Guest
Wed Jun 12, 2019 1:21 pm
On 2019-06-12 14:17, Pszemol wrote:
[...]
Quote:
Pisząc w Visual Basic 6 gostek porównywał rezultat konwersji CDbl()
No nieźle, nieźle. Myślałem, że to ja jestem dinozaurem, który w chacie
używa WinXP, a tu widzę, że ludzie jeszcze komercyjnie piszą coś nowego
pod VB6, do którego extended support skończył się w 2008.

Tak mnie
jakoś tknął ten VB6, bo pamiętam, jak mój koleżka się nim zachwycał
gdzieś pod koniec lat 90-tych.
Wojciech Piechowski
Guest
Wed Jun 12, 2019 2:47 pm
W dniu środa, 12 czerwca 2019 14:17:44 UTC+2 użytkownik Pszemol napisał:
Quote:
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ą?
Mniej więcej wszystko tak ma. "Normalne" typy zmiennoprzecinkowe (normalne, czyli float, double, zapisywane w stałej ilości bitów) odwzorowują liczby z jakąśtam dokładnością. Podczas operacji prawie zawsze wprowadza się jakąś odchyłkę. Porównywanie takich liczb na równość lub różność to źródło smrodu. Twój fix jest ok, to zdrowa praktyka na porównanie liczb zmiennoprzecinkowych: if abs(x-y)<0.00...001 then...
WP
Szyk Cech
Guest
Wed Jun 12, 2019 2:52 pm
Quote:
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ą?
Weź chłopie ić na studia (ja miałem to nawet na wieczorowych 20 lat
temu) i się doucz! Zamiast zadawać głupie pytania. Choć gdybyś dłubał w
czymś innym niż VB to byś wiedział o problemie (w każdej książce do
Asemblera czy C czy C++ to powinno być).
Cezary GrÄ
dys
Guest
Wed Jun 12, 2019 2:54 pm
W dniu 12.06.2019 o 14:29, Mateusz Viste pisze:
Quote:
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ę.
--
Cezary Grądys
czarekgr@wa.onet.pl
J.F.
Guest
Wed Jun 12, 2019 3:27 pm
Użytkownik "Szyk Cech" napisał w wiadomości grup
dyskusyjnych:Jk8ME.2$6r.0@fx19.fr7...
Quote:
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ą?
Weź chłopie ić na studia (ja miałem to nawet na wieczorowych 20 lat
temu) i się doucz! Zamiast zadawać głupie pytania. Choć gdybyś dłubał
w czymś innym niż VB to byś wiedział o problemie (w każdej książce do
Asemblera czy C czy C++ to powinno być).
Musialbym sobie przypomniec ... ale przy okazji Assemblera raczej nikt
nie poruszal takiego watku.
Przy C predzej, ale to gdzies na pograniczu.
Kto nie uczyl sie Fortranu, ten nie zna zycia :-)
J.
stary grzyb
Guest
Wed Jun 12, 2019 4:17 pm
Quote:
Kto nie uczyl sie Fortranu, ten nie zna zycia
Prawda, ale wcześniej trzeba było zaliczyć Algol.
Queequeg
Guest
Wed Jun 12, 2019 4:53 pm
In pl.misc.elektronika Mateusz Viste <mateusz@nie.pamietam> wrote:
Quote:
Prawdziwi programiści nie używają liczb zmiennoprzecinkowych.
Nie szedłbym tak daleko. Oczywiście używają ale wiedzą też, jakie są ich
ograniczenia i jak je porównywać.
--
Eksperymentalnie:
http://facebook.com/groups/pl.misc.elektronika
Guest
Wed Jun 12, 2019 5:45 pm
W dniu środa, 12 czerwca 2019 07:17:44 UTC-5 użytkownik Pszemol napisał:
Quote:
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.
Pszemol
Guest
Thu Jun 13, 2019 1:24 pm
"JDX" <jdx@onet.pl> wrote in message
news:5d00fc5f$0$522$65785112@news.neostrada.pl...
Quote:
On 2019-06-12 14:17, Pszemol wrote:
[...]
Pisząc w Visual Basic 6 gostek porównywał rezultat konwersji CDbl()
No nieźle, nieźle. Myślałem, że to ja jestem dinozaurem, który w chacie
używa WinXP, a tu widzę, że ludzie jeszcze komercyjnie piszą coś nowego
pod VB6, do którego extended support skończył się w 2008.

Tak mnie
jakoś tknął ten VB6, bo pamiętam, jak mój koleżka się nim zachwycał
gdzieś pod koniec lat 90-tych.
To raczej utrzymywanie starego kodu.
Pszemol
Guest
Thu Jun 13, 2019 1:35 pm
"Szyk Cech" <szykcech@spoko.pl> wrote in message
news:Jk8ME.2$6r.0@fx19.fr7...
Quote:
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ą?
Weź chłopie ić na studia (ja miałem to nawet na wieczorowych
20 lat temu) i się doucz! Zamiast zadawać głupie pytania.
Ale kultury osobistej Cię tam nie nauczyli... szkoda.
Quote:
Choć gdybyś dłubał w czymś innym niż VB to byś wiedział
o problemie (w każdej książce do Asemblera czy C czy C++
to powinno być).
ha ha

No brawo.
Goto page 1, 2, 3, 4, 5, 6, 7 Next