Dokładność liczb

Jeśli masz coś do powiedzenia w sprawie LabVIEW napisz. Tutaj są tematy, których nie można uściślić do innych działów.
Awatar użytkownika
Arronax8
Posty: 69
Rejestracja: 06 kwie 2012 21:25
Wersja środowiska: LabVIEW 2012

Dokładność liczb

Post autor: Arronax8 »

Nurtuje mnie taki problem, jak można otrzymać informacje o tym z jaką dokładnościa występuje dana liczba.
Inaczej mówiąc informacje o tym ile miejsc występuje po przecinku, tak dla liczby 2 - nic (0), 2.1 - 1, 2.34 - 2, 2.3453 - 4 itd.
Mam tablicę liczb i chciałbym z niej oddzielić tylko pełne liczby.
Kombinowałem nad property node - format i precision, ale nic z tego, bo wiadomo wszystkie liczby są tego samego formatu.
PiDi
Posty: 641
Rejestracja: 31 gru 2010 01:36
Wersja środowiska: LabVIEW 2017
Lokalizacja: Katowice

Re: Dokładność liczb

Post autor: PiDi »

Hmmm...
Załączniki
calkowita.png
calkowita.png (14.45 KiB) Przejrzano 8719 razy
ObrazekObrazekObrazekObrazek
Awatar użytkownika
Arronax8
Posty: 69
Rejestracja: 06 kwie 2012 21:25
Wersja środowiska: LabVIEW 2012

Re: Dokładność liczb

Post autor: Arronax8 »

Hmmm..., chyba niezybt jasno opisałem problem.
Zmiana formatu liczby z dbl na i32 nic mi nie daje.
Chcę uzyskać:
1. Mając liczbę dbl - ilość miejsc po kropce, czyli dla wartości 2 chcę wiedzieć, że nie ma kropki, dla wartości 2.456 chcę wiedzieć, że po kropce są 3 miejsca, dla 2.45363 - 5 miejsc itd.
2. Mając tablicę wartości dbl, w której są liczby typu: 2, 4.565, 3.897565, 7, 12.453, 1.1, 21 chcę oddzielić (nie zaokraglać, nie zmieniać formatu) liczby pełne od tych z kropka, czyli uzyskać tablicę liczb: 2, 7, 21.
Myślę, że teraz już zrozumiale opisałem.
may
Posty: 96
Rejestracja: 20 lut 2012 12:30
Wersja środowiska: LabVIEW 2014
Lokalizacja: Katowice / Ruda Śląska

Re: Dokładność liczb

Post autor: may »

Nie wiem czy nie mylisz trochę pojęć, bo co dokładnie ma dla ciebie znaczyć "dokładność liczby"? Liczba 3.14 jest z dokładnością 2 miejsc, liczba 3.1415 z dokładnością 4, a liczba 3.1400? Z dokładnością 4 czy dokładnością 2? Jeżeli odpowiedź na poprzednie pytanie byłaby 2, to tak naprawdę chodzi ci o znalezienie na którym miejscu po przecinku jest ostatnia niezerowa wartość, w reprezentacji dziesiętnej liczby. Bo zastosowanie zapisu zmiennoprzecinkowego (a takiego zapewne używasz) tak naprawdę trochę komplikuje to pytanie.
Nawet jeżeli chodziło by ci tylko o oddzielenie liczb całkowitych od niecałkowitych, to w zapisie zmiennoprzecinkowym to nie jest takie proste.
Jak można sprawdzić czy liczba jest całkowita?
Wydawało by się, że można ją zaokrąglić w dół i sprawdzić czy zaokrąglenie jest równe początkowej liczbie (3 zaokrąglisz do 3, porównujesz, zgadza się - jest całkowita. 3.14 zaokrąglisz do 3 porównujesz, nie zgadza się - nie jest całkowita).
Ok, możemy to napisać w LabVIEW i zobaczyć jak działa.
1.png
1.png (11.66 KiB) Przejrzano 8713 razy
Wpisujemy z palca 3, sprawdzamy, ok, jest całkowita. Wpisujemy 3.1, sprawdzamy, ok, jest niecałkowita. Strzałeczką na front panelu dekrementujemy o 0.1 w dół do 3, sprawdzamy, i co? LabVIEW twierdzi, że to liczba niecałkowita. Dlaczego tak się dzieje? Wynika to z reprezentacji zmiennoprzecinkowej liczby. Dorzuciłem bloczek number to fractional string, ustawiłem precyzję na 100 i możemy zobaczyć, że tak naprawdę pomimo, że na kontrolce wyświetla się 3 to w zmiennym przecinku zapisana jest liczba 3.00000000000000266.
2.png
2.png (29.05 KiB) Przejrzano 8713 razy
W ogólności można przyjąć, że dla liczb zmiennoprzecinkowych nie można stosować operacji "a=b", bo wyniki mogą być naprawdę różne. Możemy co najwyżej porównać z jakąś dokładnością, czyli sprawdzić czy |a-b|<d, gdzie d jest jakąś małą liczbą.
Może takie porównanie będzie dla ciebie wystarczające.
3.png
3.png (13.55 KiB) Przejrzano 8713 razy
Jeżeli nie, to możesz spróbować przekonwertować liczbę na stringa z dużą precyzją i szukając od końca, sprawdzić gdzie występuje pierwsza liczba różna niż 0 (to w zasadzie jest właśnie wyznaczenie tej "dokładności" o której mówiłeś na początku pytania), ale ostrzegam, że nawet jeżeli wpiszesz liczbę całkowitą z palca, to nie ma żadnej gwarancji, że na n-tym miejscu po przecinku nie znajdzie się coś innego niż zero.
Obrazek
TMa
Posty: 203
Rejestracja: 07 sty 2010 12:56
Wersja środowiska: LabVIEW 2017

Re: Dokładność liczb

Post autor: TMa »

W pełni zgadzam się z moim przedmówcą. Jednak to programista decyduje z jaką precyzją i w jakim formacie jest wyświetlana liczba double (zakładka Display Format we właściwościach kontrolki Numeric). Domyślnie (Automatic formatting) jest na 6 cyfr znaczacych.
Arronax8 pisze:1. Mając liczbę dbl - ilość miejsc po kropce, czyli dla wartości 2 chcę wiedzieć, że nie ma kropki, dla wartości 2.456 chcę wiedzieć, że po kropce są 3 miejsca, dla 2.45363 - 5 miejsc itd.
"Proszę Państwa oto Miś..":
Załączniki
double.png
double.png (20.81 KiB) Przejrzano 8708 razy
PiDi
Posty: 641
Rejestracja: 31 gru 2010 01:36
Wersja środowiska: LabVIEW 2017
Lokalizacja: Katowice

Re: Dokładność liczb

Post autor: PiDi »

may pisze: Możemy co najwyżej porównać z jakąś dokładnością, czyli sprawdzić czy |a-b|<d, gdzie d jest jakąś małą liczbą.
W palecie Numeric jest stała która się nazywa Machine Epsilon. Tak tylko mówię :D
ObrazekObrazekObrazekObrazek
may
Posty: 96
Rejestracja: 20 lut 2012 12:30
Wersja środowiska: LabVIEW 2014
Lokalizacja: Katowice / Ruda Śląska

Re: Dokładność liczb

Post autor: may »

PiDi pisze:W palecie Numeric jest stała która się nazywa Machine Epsilon. Tak tylko mówię :D
Aaa, słusznie, słusznie, zapomniałem o tym.

To teraz wracając do oryginalnego problemu:
Z rozważań w tym temacie powinien wyklarować Ci się obraz kodu który robi dokładnie to co chciałbyś zrobić, czyli oddziela z tablicy liczby niecałkowite.

Jeżeli jesteś jednak turbo leniwy i nie chce Ci się myśleć, kod w załączniku :P
Załączniki
tylko całkowite 8.6.vi
(14.03 KiB) Pobrany 282 razy
Obrazek
Awatar użytkownika
Arronax8
Posty: 69
Rejestracja: 06 kwie 2012 21:25
Wersja środowiska: LabVIEW 2012

Re: Dokładność liczb

Post autor: Arronax8 »

Widzę, że rozwinęła się piękna dyskusja :) Brawo Panowie! :ymapplause:
A teraz czas na nagrody:
Zwycięzcą zostaje "may" za wspaniały wywód o zapisie zmiennoprzecinkowym i podsunięcie gotowego rozwiązania :)
Pierwsze wyróżnienie należy się "TMa" za wspaniałego Misia, wielki podziw za użycie bloczku "reverse string" ;)
Drugie wyróżnienie otrzymuje "PiDi" za wskazanie stałej tak małej ;)
Moja ciekawość w tym temacie została zaspokojona, dziękuję bardzo :D
ODPOWIEDZ