-
11. Data: 2019-06-12 17:27:32
Temat: Re: Porównywanie liczb, double float
Od: "J.F." <j...@p...onet.pl>
Użytkownik "Szyk Cech" napisał w wiadomości grup
dyskusyjnych:Jk8ME.2$6...@f...fr7...
>> 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.
-
12. Data: 2019-06-12 18:17:17
Temat: Re: Porównywanie liczb, double float
Od: stary grzyb <s...@o...pl>
> Kto nie uczyl sie Fortranu, ten nie zna zycia :-)
Prawda, ale wcześniej trzeba było zaliczyć Algol.
-
13. Data: 2019-06-13 15:24:35
Temat: Re: Porównywanie liczb, double float
Od: "Pszemol" <P...@P...com>
"JDX" <j...@o...pl> wrote in message
news:5d00fc5f$0$522$65785112@news.neostrada.pl...
> 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. :-D Tak mnie
> jakoś tknął ten VB6, bo pamiętam, jak mój koleżka się nim zachwycał
> gdzieś pod koniec lat 90-tych. :-D
To raczej utrzymywanie starego kodu.
-
14. Data: 2019-06-13 15:35:17
Temat: Re: Porównywanie liczb, double float
Od: "Pszemol" <P...@P...com>
"Szyk Cech" <s...@s...pl> wrote in message
news:Jk8ME.2$6r.0@fx19.fr7...
>> 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.
> 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.
-
15. Data: 2019-06-13 15:37:55
Temat: Re: Porównywanie liczb, double float
Od: "Pszemol" <P...@P...com>
"Mateusz Viste" <m...@n...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...
> Obowiązkowa lektura na wieczór:
> http://perso.ens-lyon.fr/jean-michel.muller/goldberg
.pdf
Dzięki za linka, zapoznam się w wolnym czasie.
-
16. Data: 2019-06-13 15:39:28
Temat: Re: Porównywanie liczb, double float
Od: "Pszemol" <P...@P...com>
"J.F." <j...@p...onet.pl> wrote in message
news:5d00f430$0$17345$65785112@news.neostrada.pl...
> Użytkownik "Pszemol" napisał w wiadomości grup
> dyskusyjnych:qdqqh6$n2f$...@d...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 :-)
>>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.
-
17. Data: 2019-06-13 15:43:03
Temat: Re: Porównywanie liczb, double float
Od: "Pszemol" <P...@P...com>
"bartekltg" <b...@g...com> wrote in message
news:a843c978-5bcc-4a8a-97bd-67b77c7defe7@googlegrou
ps.com...
> Używaj funkcji abs, to samo, a czytelniej.
Słuszna uwaga - dzięki.
> W sumei to pierwsz rzecz, jakiej człowiek sie dowiaduja na jakimkolwiek
> poważniejsyzm kursie dotykającym zmiennego przecinka. Ze szczegolnym
> uwzlgędnieniem
> "Nie wykonuj porównania == i <> na liczbach zmiennoprzecinkowych"
I tyle mi zostało w głowie bo właśnie to <> mi się rzuciło w oczy
i zacząłem tam badać. Ale już wyleciała z głowy interpretacja "dlaczego".
> A jaka przyczyna? To przy okazji opisują.
>
> Zerknij na wiki, jak wyglada liczba zmiennoprzecinkowa.
>
> 2^coś *1.mantysa.
>
> 1/2 tak zapiszesz, ale 1/3 nie. 1/10 też nie.
> Zerknij tutaj,
> https://www.h-schmidt.net/FloatConverter/IEEE754.htm
l
> Liczy na single, ale zasada ta sama.
> wpisując 1.8 tak naprawdę trzymasz najbliższa
> reprezentaowalną liczbę, 1.7999999523162841796875
> Podobnie 32.8.
> 31 jest reprezentowane dokładnie.
>
> Teraz każda podstawowa operacja arytmetyczna biorąca argumenty
> a i b (oznaczamy fl(a) i fl(b) jako wartośći reprezentowane) liczy
> fl(a) (działanie) fl(b) dokładnie, a potem zapisuje jako najbliższa
> reprezentowalna wartość.
>
> W ogolności
> fl(a+b) = (fl(a)+fl(b))(1+eps), gdize ten epsylon to dokłądność
> reprezentacji.
Dzięki.
Wartościowe odświeżenie sobie w głowie ważnego detalu
z dziedziny programowania!
-
18. Data: 2019-06-13 17:28:02
Temat: Re: Porównywanie liczb, double float
Od: Dariusz Dorochowicz <_...@w...com>
W dniu 2019-06-12 o 14:17, Pszemol pisze:
> 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ą?
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
-
19. Data: 2019-06-13 23:22:06
Temat: Re: Porównywanie liczb, double float
Od: bartekltg <b...@g...com>
On Thursday, June 13, 2019 at 3:37:52 PM UTC+2, Pszemol wrote:
> "Mateusz Viste" <m...@n...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.
Pieprzenie. No, czyba, że programowanie = frontend.
> 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...
Co najwyżęj, jak obracasz walutą. Standard to chyba 1/10000 jednostki
(złotówki, dolara...).
BTW, long int to raz 32, raz 64 bity. A teoretycznie może mieć i inną wartość;-)
pzdr
bartekltg
-
20. Data: 2019-06-13 23:25:18
Temat: Re: Porównywanie liczb, double float
Od: bartekltg <b...@g...com>
On Wednesday, June 12, 2019 at 3:07:25 PM UTC+2, bartekltg wrote:
> On Wednesday, June 12, 2019 at 2:17:44 PM UTC+2, Pszemol wrote:
> > 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 :-)
>
> Ale nie działasz na liczbach rzeczywistych, ale na reprezentacji
> zmiennoprzecinkowej.
> Wszytkie trzy liczby tak naprawde mają wartość tylko zblizoną
> do tych napisanych.
>
> > 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.
>
> Używaj funkcji abs, to samo, a czytelniej.
>
> Tak, to jest poprawne rozwiązanie.
>
> > 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ą?
>
> W sumei to pierwsz rzecz, jakiej człowiek sie dowiaduja na jakimkolwiek
> poważniejsyzm kursie dotykającym zmiennego przecinka. Ze szczegolnym
> uwzlgędnieniem
> "Nie wykonuj porównania == i <> na liczbach zmiennoprzecinkowych"
>
>
> A jaka przyczyna? To przy okazji opisują.
>
> Zerknij na wiki, jak wyglada liczba zmiennoprzecinkowa.
>
> 2^coś *1.mantysa.
>
> 1/2 tak zapiszesz, ale 1/3 nie. 1/10 też nie.
> Zerknij tutaj,
> https://www.h-schmidt.net/FloatConverter/IEEE754.htm
l
> Liczy na single, ale zasada ta sama.
> wpisując 1.8 tak naprawdę trzymasz najbliższa
> reprezentaowalną liczbę, 1.7999999523162841796875
> Podobnie 32.8.
> 31 jest reprezentowane dokładnie.
>
> Teraz każda podstawowa operacja arytmetyczna biorąca argumenty
> a i b (oznaczamy fl(a) i fl(b) jako wartośći reprezentowane) liczy
> fl(a) (działanie) fl(b) dokładnie, a potem zapisuje jako najbliższa
> reprezentowalna wartość.
> W ogolności
> fl(a+b) = (fl(a)+fl(b))(1+eps), gdize ten epsylon to dokłądność
> reprezentacji.
Lepiej by było, jakbym napisał, że eps jest rzędu wielkośći reprezentacji.
Może być 0, może być jak dokładność v, dodatnia lub ujemna. Wzorkiem:
abs( eps ) < v.
pzdr
bartekltg