Problem s presnosti vypoctu typu double – Visual Basic – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Problem s presnosti vypoctu typu double – Visual Basic – Fórum – Programujte.comProblem s presnosti vypoctu typu double – Visual Basic – Fórum – Programujte.com

 

Keny0
Návštěvník
23. 2. 2010   #1
-
0
-

Ahoj, potreboval bych radu ohledne vypoctu s hodnotami typu double napr.

Dim c As Double
c = 760879.16 - 755769.087298

Me VBAcko vypocte c=5110.07270200003, ale vysledek by mel byt jen c=5110.072702, takze jde jen o tu 3ku kdesi vzadu.
Doted jsem vzdalenym desetinnym mistum nevenoval pozornost, tak nevim jestli to dela i pri jine operaci nez minus, ale
momentalne me tendle problem dost vadi, protoze musim vsude cpat funkci Round.. abych mel cislo na pozadovany pocet mist.

Vsem co se pokusi pomoct predem diky :)

Nahlásit jako SPAM
IP: 84.244.114.–
liborb
~ Redaktor
+18
Guru
23. 2. 2010   #2
-
0
-

Dělá to i při jiných operacích a bude to dělat. Prostě se s tím musíš smířit. Double je sice "dvojitá přesnost", ale ta má taky svoje meze. Podívej se na problematiku floatových čísel a pochopíš.

Nahlásit jako SPAM
IP: 85.207.166.–
Keny0
Návštěvník
23. 2. 2010   #3
-
0
-

Neco sem vyGoogloval, ale v anglictine (coz neni nic pro me ), takze pokud ma nekdo po ruce odkaz na cesky stranky, tak sem s nim. Ale hlavni jsem asi pobral - hodnota neni ulozena jako sekvence cislic, ale jako exponent a cislo pro jeho prenasobeni. Rad bych ale vedel, najaky vztah nebo neco jak zjistit, jestli se me jeste cislo ulozi "spravne" nebo jestli se jiz vlivem systemu viz vyse ulozi jen nejblize mozna hodnota.

Nahlásit jako SPAM
IP: 83.208.251.–
liborb
~ Redaktor
+18
Guru
23. 2. 2010   #4
-
0
-

Jenom by mě zajímalo, jak to chceš kontrolovat?

Nahlásit jako SPAM
IP: 91.203.96.–
Keny0
Návštěvník
23. 2. 2010   #5
-
0
-

Neco sem vyGoogloval, ale v anglictine (coz neni nic pro me ), takze pokud ma nekdo po ruce odkaz na cesky stranky, tak sem s nim. Ale hlavni jsem asi pobral - hodnota neni ulozena jako sekvence cislic, ale jako exponent a cislo pro jeho prenasobeni. Rad bych ale vedel, najaky vztah nebo neco jak zjistit, jestli se me jeste cislo ulozi "spravne" nebo jestli se jiz vlivem systemu viz vyse ulozi jen nejblize mozna hodnota.

Nahlásit jako SPAM
IP: 83.208.251.–
Keny0
Návštěvník
23. 2. 2010   #6
-
0
-

Sakra pomalej net 2x sipka zpet a pak zas nazpet a hodilo to znova post a mazani je zakazano...

Prave chci vedet, jestli je naka pomucka pro to, abych vedel kdy to 100% nemuze nastat. Jako treba, ze 5.5+3.4=8.9 a ne 8.9000000003 atd. jestli to ma treba vazbu na pocet platnych mist vstupnich hodnot nebo tak neco.

Nahlásit jako SPAM
IP: 83.208.251.–
Keny0
Návštěvník
23. 2. 2010   #7
-
0
-

Dim a, b, c, d As Double
a = 760879.16
b = 755769.087298
d = b - a
a = 10 ^ 6 * a
b = 10 ^ 6 * b
c = (b - a) / 10 ^ 6

Todle me prijde hrozne divny, ze ten sami vypocet neni ekvivalentni (d<>c).
No dotaz zni, pokud budu tedy pocitat pouze s celymi cisly (viz priklad 12 platnych mist), bude vypocet vzdy presny? Nebo nakej odkaz/navod jak se s timdle vyrovnavaj profici.

Nahlásit jako SPAM
IP: 83.208.251.–
liborb
~ Redaktor
+18
Guru
24. 2. 2010   #8
-
0
-
Nahlásit jako SPAM
IP: 85.207.166.–
Keny0
Návštěvník
24. 2. 2010   #9
-
0
-

V tom co delam se hodnoty dale porovnavaji, casto s velice podobnymi cisly, takze u velke casti maji vyznam predevsim vzdalenejsi desetinna mista.
Nejspis jsem zvolil spatnej typ (nepotrebuju rozsah pro 300mistna hodnoty), potrebuju ale typ pro presne hodnoty s max.
8 misty vlevo od des. tecky a 6 des. misty, s dostatecnou rezervnou pro bezne matematicke operace s takovym cislem (nejvic
co pouziju je asi ^2).
Programuju ve VBA (pod Excelem 2003). Moc na vyber typu co by splnoval pozadavky viz vyse asi nemam - Currency ma dost maly rozsah a Decimal neni momentalne podporovan, nicmene je pry soucasti typu, kteremu jsem se doted snazil radsi vyhybat - Variant (16 bytes). Uz ted (jsem cca. v pulce programu) trva vypocet pri prumernem vtupnim objektu (cekam i 10x vetsi)
cca 5 minut... tak doufam, ze nebude mit ten Variant nakej drastickej vliv na narust vypocetniho casu.

Nahlásit jako SPAM
IP: 84.244.114.–
liborb
~ Redaktor
+18
Guru
25. 2. 2010   #10
-
0
-

Variant není to co hledáš. Variant je typ používaný pro COM Automation a lze do něj "schovat" jakýkoliv jiný typ.

Napadají mě 2 možnosti. Buď proveď "převod" na celá čísla (vynásobit dostatečně velkým číslem). Nebo pokud porovnáváš 2 floatová čísla a liší se na x-tém desetinném čísle, tak provést jejich rozdíl a porovnávat, jestli je ten rozdíl <= než nějaký "epsilon".

Nahlásit jako SPAM
IP: 85.207.166.–
Keny0
Návštěvník
25. 2. 2010   #11
-
0
-

Co se pise ve VBA:
Variant(with numbers) 16 bytes Any numeric value up to the range of a Double .
Variant(with characters) 22 bytes + string length Same range as for variable-length String
+ teda dokaze zapsat cokliv jinyho

Takze jakmile napisu neco jako:
Dim a as Variant
a=755769.087297 'zapise hodnotu nejspis jako naky floatovy typ (double?)
a=CDec(755769.087297) 'zapise hodnotu jako Decimal - coz me prijde jako jediny reseni

Problem je, ze nevim o zadnym celociselnym typu, ktery by hodnotu po prenasobeni uchoval (nebo s ni jeste mohl provadet matematicke operace).
Ty cisla co porovnavam se klidne lisi i v nejvyssim radu (nicmene vetsi cast se bude lisit nekde dal), ale pokud bych to pouzil, tak prave netusim, jak urcit desetinny rad (nebo to epsilon). Proste kde konci presnost hodnoty a zacinaji cislice nejblize mozne ulozitelne hodnoty daneho typu.

Nahlásit jako SPAM
IP: 83.208.251.–
liborb
~ Redaktor
+18
Guru
26. 2. 2010   #12
-
0
-

A proč nepoužíváš typ Decimal přímo? Tím, že ho "schováváš" do Variantu si vlastně umýslně ještě zpomaluješ program, protože se před každým výpočtem musí zjisit, jakého typu je hodnota schovaná ve Variantu. A jinak je to dobrá volba, resp. podle toho co píšou v dokumentaci je z principu přesnější než double (je to vlastně ta první možnost, o které jsem psal).

Epsilon si volíš ty, tím říkáš jakou chceš dosáhnout přesnost.

Nahlásit jako SPAM
IP: 85.207.166.–
Keny0
Návštěvník
26. 2. 2010   #13
-
0
-

Decimal primo.. viz par postu zpet, decimal neni momentalne ve VBA podporovan. Primo se tam pise, ze k jeho pouziti se ma pouzit Variant (jehoz podtypem Decimal je) s pretypovanim CDec.

No ja chci presnost co nejvyssi, ale nema prece cenu porovnavat uplne konce hodnot, kde si float typ "pise co chce", chtel bych porovnavat jen po cast co je "presne". Nedokazu si prestavit co se jeste zapise naprosto presne a co jiz se musi nahrazovat hodnotou nejblizsi. Nebo jestli ma vubec cenu u floatu pouzivat neco jako If a=b then... vzhledem k tomu, ze stejna hodnota muze byt zapsana pokazde trosku jinak.

Nahlásit jako SPAM
IP: 83.208.251.–
liborb
~ Redaktor
+18
Guru
1. 3. 2010   #14
-
0
-

Aha, tak s tím Decimal mi to nějak uniklo.

A ta přesnost ... pro float opravdu skoro nemá smysl if (a == b) then ..., ale (zrovna nedávno to tu proběhlo v PHP) právě přes epsilon nebo jinak řečeno přes zvolenou přesnost tj. něco jako:




if (abs(a - b) <= epsilon) then ...


Nahlásit jako SPAM
IP: 85.207.166.–
Keny0
Návštěvník
2. 3. 2010   #15
-
0
-

Pokud chci to epsilon co nejmensi, melo by se rovnat maximanimu moznemu rozdilu mezi hodnotou a jejim floatovym zapisem... nakej napad jak to vycislit?

Nahlásit jako SPAM
IP: 84.244.114.–
liborb
~ Redaktor
+18
Guru
4. 3. 2010   #16
-
0
-

Jak jsem psal, epsilon si volíš sám. A pokud tvoje volba to nejmenší možné, tak to je závislé na "mašině". Některé jazyky ho umí vyčíslit (nebo se o to alespoň snaží): VB Double.Epsilon = 4.94065645841247e-324, ale to není přesnost daná strojem, ale nejmenší kladná hodnota větší než 0. Neboli asi bude potřeba zapojit strejdu googla (možná i tetu wiki :smile1: ) a pokud nic neporadí, tak si zvolit svojí přesnost (experimentálně zjištěnou a vyhovující).

Nahlásit jako SPAM
IP: 85.207.166.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 9 hostů

Podobná vlákna

Jmeno pole typu double — založil cecil

Problem s double — založil braba

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý