Wyjaśnianie klientom precyzji zmiennoprzecinkowej [zamknięte]

23

Jaki jest najlepszy sposób wyjaśnienia klientom problemu zaokrąglania zmiennoprzecinkowego ?

wiem

http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html

jak również wpisy w C ++ FAQ i różne inne strony skierowane do programistów i naukowców, ale czy istnieje strona internetowa, artykuł lub wyjaśnienie, skierowane do „stałych” klientów o ograniczonym matematycznym lub naukowym doświadczeniu? (dla których powyższe referencje są płaskie).

Jeśli zostanie utrzymany lub pochodzi od znanej i uznanej instytucji lub korporacji, tym lepiej, biorąc pod uwagę, że, jak niektórzy z was mogli doświadczyć, wytłumaczenie tego może być trochę skomplikowane.

Eric Grange
źródło
1
Nie zawracałbym sobie głowy ...
John Shaft
1
To naprawdę fantastyczne pytanie, +10 gdybym mógł. Częsty problem dla programistów.
Cody Gray
2
To nie jest problem ze szczegółami, to odpowiedź na pytanie, dlaczego dodanie tego, co wygląda na liczby precyzyjne o 2 cyfrach dziesiętnych, kończy się na 5.9999999, a nie na 6, i dlaczego musisz określić precyzję zaokrąglania, gdy „oczywisty” wynik nie powinien mają więcej niż dwie cyfry dziesiętne. Albo dlaczego czasami 2 minus 2 nie zawsze jest zerem i nie wygląda na oszalałego głupca.
Eric Grange
9
@Eric Grange: jeśli Twoi klienci uważają te problemy z precyzją za błąd, oznacza to, że jest to błąd i musisz znaleźć sposób, aby go naprawić (być może nie używając float). Nie dbają o to, skąd bierze się ten problem z precyzją. Nie dbają o to, jak działa twoje oprogramowanie. Chcą tylko, żeby to działało.
David
3
@Eric: Zastosowanie zmiennoprzecinkowe jest szczegółem implementacji. Powtarzam moje pytanie, w którym nie pytam o coś wyjaśnionego w pytaniu, a które najwyraźniej nie wyjaśniłem (przepraszam): w jakim kontekście i dlaczego omawiasz użycie zmiennoprzecinkowe z klientem?
Tom Anderson

Odpowiedzi:

8

Znajduję prosty sposób na wyjaśnienie tego, aby to wykazać . Przedyskutuj, w jaki sposób dzielenie xprzez liczbę, a następnie pomnożenie przez ten sam numer powinny wrócić do Ciebie x- poproś klienta, aby zgodził się, że zawsze tak powinno być. Następnie zrób stary (100 / 3) * 3kalkulator; pokazują, że wartość nie powraca, jak można się spodziewać, do 100. Gdy większość ludzi widzi, że proste matematyki „się psują”, wówczas „dostają” się niebezpieczeństwo liczb zmiennoprzecinkowych, w których ważna jest dokładność (choć intuicyjnie sposób, zamiast do niskiego poziomu, do którego trafia artykuł, na który wskazujesz).

Niestety obecnie większość na wpół przyzwoitych kalkulatorów (z pewnością wszystkie naukowe, które widziałem i więcej niż kilka podstawowych) jest w stanie sobie z tym poradzić - przypuszczam, że przechowują dodatkowe cyfry poza tym, co można wyświetlić i zaokrąglić - tak też jest sprawdź, jak sprytny jest Twój kalkulator, zanim zrobisz to przed klientem.

Scott
źródło
1
Tak, prawie wszystkie kalkulatory przechowują co najmniej 2 dodatkowe cyfry, więc musisz dodać kilka mnożników do mieszanki, co powoduje, że wyjaśnienie jest mętne, a IME sprawia, że ​​myślą, że próbujesz je oszukać. Pierwiastek kwadratowy wymaga mniej operacji, ale pierwiastek kwadratowy jest już poza codzienną domeną stałych klientów.
Eric Grange
2
@Scott Wypróbowałem tutaj kilka kalkulatorów, żaden nie wykazywał problemów z (100/3) * 3, nawet (100/3) * 3-100 nie wykazywał problemów ... Excel też dobrze to rozumie.
Eric Grange
9
Weźmy na przykład pieniądze, które mają idealną ograniczoną precyzję. Wyjaśnij, że dzielisz jednego dolara, wtedy każda osoba dostaje 33 centy, a jeden grosz jest tracony w zaokrąglaniu. Każdy może się do tego odnosić.
Inca
4
Nie przejmuj się kalkulatorem. Podziel 1 na 3 na papierze, zachowując trzy cyfry znaczące.
David Thornley
5
@omegacentauri, jeśli uważasz, że to wyjaśnienie pomaga, domyślam się, że nie rozmawiasz często z klientami.
jhocking
5

Nie sądzę, że istnieją skróty. Musisz:

  • Dowiedz się, czym jest zmiennoprzecinkowy i jak się zachowuje.

Lub, jeśli jest to zbyt wymagane, musisz po prostu:

  • Zaakceptuj, że komputer nie da dokładnych wyników liczbowych.

Może przykład z liczb niewymiernych pomaga (chociaż kwestie zmiennoprzecinkowych dotyczą liczb wymiernych, jak również): sqrt(2) ~ 1.414. Potem 1.414^2 = 1.999396. Bez względu na to, ile cyfr wybierzesz, nigdy nie wrócisz do oryginału 2. Ok 4 poprawne cyfry znaczące mogą być dopuszczalne, ale zastanów się, co się stanie, gdy tego rodzaju „błędy zaokrąglania” będą się kumulować. Tam jest prawdziwe niebezpieczeństwo.

Joonas Pulakka
źródło
2
Ja osobiście znam i rozumiem, ale dla niektórych osób „zmiennoprzecinkowy” jest już terminem obcym, więc potrzebujesz czegoś więcej niż matematycznego lub naukowego wyjaśnienia, aby wyjaśnić, że to, co potrafią obliczyć w ich głowie, ich drogie komputery i oprogramowanie mają problemy z poprawnością ;) Również pierwiastek kwadratowy znajduje się poza codzienną domeną stałych klientów.
Eric Grange
5

Najpierw ustal, na co narzekają. Transakcje finansowe muszą być wykonywane dokładnie, z odpowiednią liczbą miejsc po przecinku i odpowiednimi zasadami zaokrąglania. Zazwyczaj oznacza to utrzymanie całkowitej liczby jednostek walutowych i upewnienie się, że arytmetyka jest wykonana poprawnie.

Alternatywnie, mogą narzekać na nadmierne wyświetlanie, a zmniejszenie liczby znaczących cyfr może być wszystkim, co jest konieczne.

W przypadku liczb zawsze możesz spróbować wymyślić trzycyfrową liczbę dziesiętną x, tak że x * 3 wynosi 10. To pokazuje podstawowe zasady.

Pozostają dwa problemy. Jednym z nich jest to, że niektóre liczby można wyrazić dokładnie w postaci dziesiętnej, ale nie binarnej (powiedzmy 3,15). Trudno to wytłumaczyć osobom nietechnicznym, a najlepszym rozwiązaniem jest uniknięcie tego, ponieważ nie ma wystarczającej liczby znaczących cyfr, aby się pojawił. Drugi to klient, który wie trochę, wystarczy wiedzieć, że arytmetyka komputerowa nie zawsze jest dokładna, i nie wystarczy, aby zdać sobie sprawę, że arytmetyka dziesiętna nie zawsze jest dokładna. Kłóciłem się z kilkoma z nich i nie mam nic przydatnego do zgłoszenia.

David Thornley
źródło
3

Liczby zmiennoprzecinkowe w komputerach używają wartości binarnych, tak jak mamy system liczbowy z jedynkami, dziesiątkami, setkami i dziesiątymi częściami, setne kolumny, liczby zmiennoprzecinkowe w komputerach faktycznie mają jedynki, dwójki, czwórki i połówki, ćwiartki i kolumny ósme. Jeśli klient zna stopy / cale, przypomnij mu o tym, jak zwykle używasz ułamków cala o podstawie 2.

Teraz spróbuj przechowywać 10 centów jako połączenie połówek, ćwiartek, ósmych dolara. To po prostu nie działa:

.00011001100110011. . . ( powtarza się w nieskończoność )

To tak samo, jak wzięcie standardowej imperialnej taśmy pomiarowej i próba zmierzenia jednej dziesiątej cala. Nie możesz tego zrobić dokładnie. Nie ma reprezentacji 1/10 jako X / Y, gdzie X i Y są liczbami całkowitymi, a Y jest potęgą 2.

Właśnie dlatego mamy typy danych dziesiętnych, które używają 4 bitów do przechowywania każdej cyfry dziesiętnej , więc wróciliśmy do podstawowej reprezentacji 10. Kompromis dotyczy przestrzeni i wydajności (około 100% wydajności, z tego co przeczytałem).

Scott Whitlock
źródło
1

Powiedz im, że podobnie jak ich konto bankowe nie może pomieścić 4,4423425908459032890413 ... dolarów (to 4,44 USD lub 4,45 USD, nic pomiędzy), komputer nie może łatwo zapisać liczby z dowolną dokładnością. Niedoskonałości pamięci masowej prowadzą do niedoskonałości obliczeń.

(Jest to nieco oszustwo, ale powinno dać im pojęcie o tym, na czym polega problem).

quant_dev
źródło
2
Niestety, to wyjaśnienie nie działa, ponieważ problem precyzji może się zdarzyć przy sumowaniu liczb, z których wszystkie mają tylko dwie cyfry precyzji na początek.
Eric Grange
1
Dwie cyfry dziesiętne . Tak, zgadzam się, dociekliwy klient zauważy w nim dziury. Ale potem możesz uderzyć ich dyskusją na temat reprezentacji binarnej - poprosili o to ;-)
quant_dev
Cóż, już próbując wyjaśnić zmiennoprzecinkowe, IME od razu zaczynają myśleć, że próbujesz ich zbzikować, co może być złagodzone, jeśli przyjdzie w prosty, zrozumiały sposób lub od znanej instytucji lub korporacji. :)
Eric Grange
1
@Eric Math jest trudny, chodźmy grać w baseball: P
quant_dev
1
Zapytaj, czy dokładniej jest zmierzyć coś z dokładnością do 1/10 "lub z dokładnością do milimetra. To drugie jest bardziej precyzyjne, ale obiekty, które są dokładną wielokrotnością 0,1", nie będą dokładną wielokrotnością 1 mm, chyba że są również dokładna wielokrotność 5 "(dokładnie 127 mm). Dodanie rozmiaru dwóch obiektów 2,54 mm, które są mierzone z dokładnością do 0,1", daje łączny rozmiar 0,2 "; sumowanie rozmiarów zaokrąglonych do najbliższego milimetra da 6 mm, mimo że rzeczywisty rozmiar powinien wynosić 5,08 mm
supercat
1

2/3

Poproś, aby zapisali dokładną odpowiedź na dwa podzielone przez 3.
Ponieważ odpowiedź „trwa wiecznie”, możesz to wskazać.

Korzystanie z 1/3 też by działało, ale 2/3 jest być może nieco lepszym przykładem, ponieważ zaokrąglanie daje (np.) .6666667, podczas gdy .3333333 wygląda na to, że można go po prostu obciąć.

Michael Durrant
źródło
0

Podczas wykonywania obliczeń komputery zwykle używają aproksymacji liczb (np. Zamiast 1000000.7 używają 1000000), ponieważ stosowanie aproksymacji jest znacznie szybsze. Problem polega na tym, że kiedy wykonujesz obliczenia z przybliżeniami, otrzymujesz przybliżenia z powrotem. Zwykle działa to całkiem dobrze, ale czasami prowadzi do nieoczekiwanych rezultatów.


źródło
Naprawdę nie rozumiem, co tu mówisz. „Ponieważ stosowanie przybliżeń jest znacznie szybsze”? Czasami arytmetyka liczb całkowitych jest co najmniej tak szybka i to jest precyzyjne. Czasami nie ma alternatywy (jak w przypadku drukowania pierwiastka kwadratowego z 2).
David Thornley,
Cóż, próbujesz wyjaśnić marketingowemu facetowi, dlaczego komputery nie mogą w rzeczywistości reprezentować liczb niewymiernych lub w zasadzie dowolnej liczby w wielkim schemacie rzeczy (och, a potem możesz dać mu szybki wykład na temat nieracjonalności \ pi: coś na temat Seria Fouriera może być urocza). Przybliżone to słowo, które ludzie mogą zrozumieć. Zbliżasz się do tego z punktu widzenia kogoś, kto wie, że wszystkie liczby nie są równe.
0

Niektóre obliczenia są wykonywane zgodnie z pewną regułą prawną. Na przykład, jeśli chcesz obliczyć, ile podatku dochodowego należy zapłacić od rocznego dochodu podlegającego opodatkowaniu w wysokości 79,245,18 EUR w Niemczech, istnieje tylko jedna poprawna odpowiedź. Masz rację lub źle. Jeśli masz rację, nie musisz wyjaśniać, jak działa arytmetyka zmiennoprzecinkowa. Jeśli się pomylisz, nie musisz wyjaśniać, jak działa arytmetyka zmiennoprzecinkowa, musisz naprawić uszkodzony kod.

Czasami wyświetlasz wyniki, które nie wyglądają dobrze. Na przykład, jeśli przeliczasz 13 297,47 USD na dwie funty dziesiętne, a następnie przeliczasz tę kwotę z powrotem na USD, możesz nie otrzymać 13 297,46 USD, ale 13 297,45 USD lub 13 297,47 USD. To nie ma nic wspólnego z arytmetyką zmiennoprzecinkową. Jest to problem nieunikniony i lepiej wyjaśnić, dlaczego jest on nieunikniony. (Powinieneś także wiedzieć, dlaczego problem nie występuje, gdy przeliczasz z GBP na USD i odwrotnie).

Istnieją inne możliwe wyniki, które nie wyglądają dobrze. Jeśli konwertujesz liczby na wartości procentowe, wartości procentowe powinny sumować się do 100%, ale mogą nie. Jeśli wyświetlasz cztery wartości procentowe z dwoma miejscami po przecinku, cztery wyświetlane wartości procentowe mogą sumować się do 99,99% lub 100,01%. Nie ma nic wspólnego z arytmetyką zmiennoprzecinkową. Nadal powinieneś być w stanie wyjaśnić, dlaczego.

Następnie zdarzają się sytuacje, w których nieostrożne stosowanie arytmetyki zmiennoprzecinkowej prowadzi do niewłaściwych wyników. Na przykład a + b + c zwykle nie jest tym samym, co b + c + a. Jeśli to powoduje problem, nie ma nic do wyjaśnienia, to jest coś, co naprawiasz.

gnasher729
źródło