Fórum pro uživatele kancelářského balíku OpenOffice | LibreOffice
 

#1 Re: Chyba v programu » Chybný výsledek funkce int() v makru pro vypočtený argument 1,731 » 11. 8. 2018 10:34:33

lp. napsal(a)
mrmr9 napsal(a)

[Kolik je podle vás 1,731 x 1000 ? Podle mě to je 1731 a nikoliv 1730,99999999999999999999......
Tady není přece co zaokrouhlovat.

Asi se budete muset smířit s tím, že zadaná čísla program neukládá přesně tak, jak byla zadána, ale převede je na jejich přibližnou hodnotu. S těmito přibližnými hodnotami pak provádí výpočty v plovoucí čárce. To také není matematicky úplně přesná operace.

Prostě, používat INT pro zaokrouhlování není dobrý nápad.

Tomu vcelku rozumím, že procesor asi neprovádí výpočty v desítkové soustavě a na určitém desetinném místě dojde k zaokrouhlení, resp. nepřesnosti. To by mělo řešit povýšení o řád a zaokrouhlení případně váš návod, jak to obejít. Díky za něj.
Rozumím i tomu, že takové nepřesné číslo se pak uloží do proměnné.
Ovšem hlava mi fakt nebere, proč když si tu proměnnou zobrazím po násobení, zobrazí se zaokrouhlená. Je to někde popsané, že funkce Print nebo MsgBox zaokrouhluje? Případně poradíte, jak si pro kontrolu zobrazit sutečně uložený obsah proměnné, se kterým probíhají výpočty a ne zaokrouhlený? Pokud Print zaokrouhluje a je to někde popsané, pak ok. Pokud ne, tak potom kód viz. níže se nutně musí nejen mě jevit jako chyba.

Cislo = 1.731*1000
Print(Cislo) REM zobrazí 1731
Print (INT(Cislo)) REM zobrazí 1730

#2 Re: Chyba v programu » Chybný výsledek funkce int() v makru pro vypočtený argument 1,731 » 11. 8. 2018 10:22:24

neutr napsal(a)

Opravdu je to chyba i když jsem netestoval mnoho variant. Možná jde o to, že výpočet je realizován logaritmováním a zde je něco upraveno kvůli zrychlení nebo jde o obyčejný kiks.
     Právě proto jsem doporučil zvětšit číslo a ořezat až podíl na správnou velikost. Také je dost dobře možné, že tato chyba přetrvává hodně dlouho. Nevyskytuje se vždy a těžko se něco takového hledá. Faktem je, že když by se jednalo o prosté vynásobení chyba nevznikne. Takže pro omezení desetinných míst musíte pro jistotu vynásobit o řád výše, podělit tou desítkou a tohle poslat na ořezání i když i tohle by se mělo důkladně otestovat.
     Jde o to odkud čísla berete. Může jít o přesnost podle zobrazení a tam by se to asi mohlo stát - vidíte zaokrouhlenou hodnotu kterou načítáte. Ale tady je zřejmé, že je to chyba i bez načítání zaokrouhlených hodnost.
     Někdy by bylo potřeba zaokrouhlit jinak - běžně potřeba účetních osnov, daňových přiznání ap. Na to by platila asi emulace vzorců sešitu, nebo vypálení vzroce makrem někam kde to nevadí, načíst zpětně jen jako hodnotu, pomocný vzrec smazat a je po legraci.

Díky za upřesnění. napoprvé mi nějak nedošlo, že posunutím o řád výš a zaoruhlením se mohu dostat na požadovaný výsledek bez ohledu na nepřesnost výpočtu násobení na x-tém desetinném místě.

#3 Re: Chyba v programu » Chybný výsledek funkce int() v makru pro vypočtený argument 1,731 » 10. 8. 2018 15:34:01

lp. napsal(a)

O žádnou chybu se nejedná. Je to vlastnost.

INT zaokrouhluje dolů na nejbližší celé číslo.

Použijte např. Int(cislo*1000 + 1e-13) nebo normálně zaokrouhlujte

Tomu moc nerozumím, jak to souvisí s mým příkladem:

Sub Main
Cislo=1.731
Print(Int(cislo*1000))
End Sub

Kolik je podle vás 1,731 x 1000 ? Podle mě to je 1731 a nikoliv 1730,99999999999999999999......
Tady není přece co zaokrouhlovat.

#4 Re: Chyba v programu » Chybný výsledek funkce int() v makru pro vypočtený argument 1,731 » 10. 8. 2018 15:14:34

neutr napsal(a)
mrmr9 napsal(a)

Verze: 5.4.6.2 pro Mac, možná i jiné:
Nevím, kde je chyba, ale  procedura níže vrátí výsledek 1730 namísto očekávaných 1731. Pro jiné hodnoty např. 1,732 nebo 1,7311 a pod. funguje korektně a vrací očekávaný výsedek tedy např. 1732 nebo 1731. Zlobí to jen pro hodnotu 1,731, se kterou se provede nějaký výpočet. Samotné int(1731) vrací správný výsledek 1731.

Sub Main
Cislo=1.731
Print(Int(cislo*1000))
End Sub

Obdobný výpočet používám ve funkci na zkrácení čísla na 3 desetinná místa:
vysledek=int(x*1000)/1000 resp univerzální funkce pro zkrácení čísla na určitý počet desetinných míst.

Tuší někdo, proč tak elementární výpočet zlobí u téhle jediné hodnoty (možná jich bude víc, ale zatím jsem na jinou nenarazil).
Jak to napsat, aby se na výpočet dalo spolehnout?

     Já mám dojem že chyba je v zápisu toho INT - tato funkce zaokrouhluje. Takže jde spíš o to, jak opravdu vypadají čísla. Otestujte :

Sub Main
 Cislo=1.731
 Print cislo*1000
End Sub

     Je mi jasné že je to pod nějakým složitějším výpočtem a nedá se takto snadno dovodit proč to někdy jde a někdy nikoliv. Ale domnívám se že správné řešení by mohlo být například takto :

Sub Main
 Cislo=1.731
 Print INT(cislo*10000)/10
  'Nebo třeba
 Print INT((cislo*10000)/10)
End Sub

     Nicméně potvrzuji, že jde o chybu kterou dělá také verze Libre Office: 6.1.0.3
ID sestavení: efb621ed25068d70781dc026f7e9c5187a4decd1
Vlákna CPU: 2; OS: Windows 10.0; Vykreslování UI: výchozí;
Národní prostředí: cs-CZ (cs_CZ); Calc: group threaded

Díky za reakci. Print(Cislo*1000) odzkoušeno, výsledek 1731, tam problém není. Problém je při použití INT (případně i FIX). Zajímavé je, že když je v kódu jen Print(INT(1731)), je to ok a výsledek je korektní 1731. Jakmile se ale udělá int z hodnoty 1731, která vznikne výpočtem, tak je hodnota INT chybná. Přitom výsledky výpočtu jsou ok.

Ten druhý příklad, resp. obě varianty - vynásobit o řád víc a podělit deseti kupodivu funguje pro 1,731 bez chybně. Nevím ale, jestli se na to dá spolehnout pro další čísla :-( Zpracovávám těch hodnot několik tisíc, kde pro některá porovnání potřebuju číslo zaříznout za třetím desetinným místem bez zaokrouhlení.

Zkusil jsem testnout tohle:

Sub Main
For N = 1000 to 2000
	X = INT((N/1000)*1000)
	Y = FRAC((N/1000)*1000)
	If X <> N Then MsgBox("Chyba " & X & "  " & N & "  " & Y)
Next N
End Sub

Teoreticky by to mělo proběhnout bez zobrazení chyby, ale vyhazuje to chybu na více hodnotách, zpravidla lichých. Tak to asi nebude problém jediného čísla a moc bych se na funkce INT a FIX nespoléhal.

Nevím kam nebo jak se to dělá, ale dá se ten problém někam vyreportovat, aby to časem někdo opravil?

#5 Chyba v programu » Chybný výsledek funkce int() v makru pro vypočtený argument 1,731 » 10. 8. 2018 06:30:13

mrmr9
Odpovědí: 11

Verze: 5.4.6.2 pro Mac, možná i jiné:
Nevím, kde je chyba, ale  procedura níže vrátí výsledek 1730 namísto očekávaných 1731. Pro jiné hodnoty např. 1,732 nebo 1,7311 a pod. funguje korektně a vrací očekávaný výsedek tedy např. 1732 nebo 1731. Zlobí to jen pro hodnotu 1,731, se kterou se provede nějaký výpočet. Samotné int(1731) vrací správný výsledek 1731.

Sub Main
Cislo=1.731
Print(Int(cislo*1000))
End Sub

Obdobný výpočet používám ve funkci na zkrácení čísla na 3 desetinná místa:
vysledek=int(x*1000)/1000 resp univerzální funkce pro zkrácení čísla na určitý počet desetinných míst.

Tuší někdo, proč tak elementární výpočet zlobí u téhle jediné hodnoty (možná jich bude víc, ale zatím jsem na jinou nenarazil).
Jak to napsat, aby se na výpočet dalo spolehnout?

Zápatí

Používáme FluxBB