Zpřesnění výpočtu   zodpovězená otázka

Algoritmy, .NET

Mám příklad:

 Dim DesetCislo As Double = (Abs((0.9035 - 0.903) / 2))

a Visual Basic mi vyplivne že

DesetCislo = 0.00024999999999997247

což je pro mé potřeby velmi nepřesné. Znamená to, že jsem se dostal na samotné hranice VisualBasicu a mám smůlu?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Co se vám zdá na tomto čísle nepřesné? Přesnějšího výsledku nedosáhnete, není to žádný MATLAB. Kromě toho není toto omezení Visual Basicu, ale datových typů .NET Frameworku, které VB.NET adaptuje.

nahlásit spamnahlásit spam -2 / 2 odpovědětodpovědět

Pan Linhart nemá pravdu, přesnějšího výsledku samozřejmě dosáhnout můžete - stačí použít datový typ Decimal.

Double je 64-bitový a dokumentace hovoří o přesnosti na 15 až 16 číslic.

Decimal je oproti tomu 128-bitový a má mnohem menší rozsah než Double (proto se Vám například s výsledkem nestane to, co při použití Doublu - u Vašeho příkladu je přesný výsledek 0.00025, ale program Vám vrátil číslo jiné i přes to, že 0.00025 pomocí Doublu vyjádřit lze) a poskytuje vysokou přesnost (28 až 29 číslic). Nevýhoda bohužel je, že třída Math ve většině svých funkcí tento typ nepodporuje.

Výsledek Vašeho příkladu za použití typu Decimal vyjde naprosto přesně 0.00025.

Ukázka použití v C#: decimal desetCislo = Math.Abs(0.9035m - 0.903m) / 2m;

('m' za číslem říká, že je typu decimal)

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Ondřej Linhart:

"není to žádný MATLAB"

Přesně jste to trefil, ve škole počítáme v matlabu příklady s přesností na 6 desetiných míst a když jsem si to zkusil napsat ve VB net tak jsem se dostával k trochu jiným výsledkům. Jedná se o to, že pomocí určitého algoritmu se počítá kořen rovnice a výsledek se furt v každém kroku zpřesňuje. Respektive bylo zajímavé, že když se chci ve VB net dostat ke stejně přesnému výsledku tak mi to počítá na 10 kroků (interaci) a v Matlabu to počítáme na 18 kroků (interaci). Zajímavé je že Matlab mi stejný příklad spočítá s jinou chybou než VB net. Chyba je sice stejného řádu, ale její hodnaota je oproti VB záporná (není to pravidlo). Tudíž u tohoto příkladu Matlab není ani přesnější ani horší, ale počítá jinak. Je zde vidět, že numerika, je docela zajímavá část matematiky, když chce člověk něco spočítat přesněji.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Vím že existuje typ Decimal s vysokou přesností a také jsem to chtěl původně napsat, jenže výsledek 0,000249999999999972 vs. 0,00025 mě zmátl...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nutné je ale podotknout, že Decimal je v paměti reprezentován v desítkovém zápisu (jednotlivé desítkové číslice jsou zakódovány po 4 bitech), takže počítání s tímto datovým typem je o dost pomalejší než standardní numerika.

Díky tomu v něm ale zaokrouhlování neudělá takovou chybu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Mě to s decimal vyšlo úplně shodně jako s double, takže špatně.

Pomohlo až

Dim DesetCislo As Double = Math.Round(Math.Abs((0.9035 - 0.903) / 2), 15)

:-)

Ale stejně nechápu proč je tam ta odchylka, když výsledek je úplně jasný a není ani třeba tolik přesnosti ?

Docela mě to děsí.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback