![]() |
|
Zahadný problém v Delphi - Printable Version +- Audioweb.cz (https://www.audioweb.cz) +-- Forum: Ostatní (https://www.audioweb.cz/forumdisplay.php?fid=16) +--- Forum: Smetiště (https://www.audioweb.cz/forumdisplay.php?fid=21) +--- Thread: Zahadný problém v Delphi (/showthread.php?tid=20761) |
Zahadný problém v Delphi - antonio - 14. 5. 2015 Vytvořil jsem vypisování názvů jednotlivých sekcí z ini souboru podle hledané hodnoty v sekci, konkrétně vyhledávání podle Re. Ukázka sekce v ini souboru: Kód: [18Sound 10NMB420]
Qms=4,6
Qes=0,36
fs=65
Mms=31,5
Dd=20,5
Re=10,5
Hc=12
Hg=8
Pe=350
Le=0,4
URL=http://www.eighteensound.com/Co je zajímavé, že pokud je Re=2,5, tak zadáním rozmezí při vyhledávání 2,5 a 2,5 (min (Edit123) a max (Edit124)) podle tohoto kódu: Kód: with Relist do if Rebox.Checked then begin
Ref:=StrToFloat(ReadString(vypis.Strings[i],'Re',''));
if (Ref>=StrToFloat(Edit123.Text)) and (Ref<=StrToFloat(Edit124.Text)) then
Add(IntToStr(i)) else Add('-1') end else Add(IntToStr(i));funguje, a položka je nalezena. A teď to příjde! Je-li hodnota 2,6, záznam se nenajde. Do max je nutné zapsat 2,601 a co je ještě zajímavější, že změním-li max na 2,60000000000000001 opět se nic nenajde a hodnota 2,60000000000000000000000000000001 je podle Delphi menší než 2,6. V případě hledání 2,7 je situace stejná. V případě 2,8 je nutno do minima zadat 2,79... Co to má být?
Zahadný problém v Delphi - The_P - 14. 5. 2015 Delphi neznam, ale obecne mne napada, ze je treba floaty porovnavat s nejakou toleranci, protoze float == float ti nemusi vratit true i kdyz jsou dle vypisu nutne stejne. Nasel jsem neco na SO: http://www.delphibasics.co.uk/RTL.asp?Name=CompareValue ale jak rikam, Delphi neznam takze nevim v jakem formatu jsou ty floaty ulozene v pameti apod, ani jestli ta fce je soucasti normalniho Delphi apod. Zahadný problém v Delphi - ythren - 14. 5. 2015 no ono číslo uložené jako float je vždycky nepřesné. čísla jako 2,60000000000000001 2,60000000000000000000000000000001 jsou už poněkud nad rámec přesnosti a prostě se ti z toho udělá nejbližší číslo co to zvládne, což může být např 2,5999999 nebo podobně. a zobrazování může být zaokrohlované. float hodnoty se nedají použít na přímou shodu vždycky to musíš brát s určitou tolerancí například shoda by se dělalala jako float tolerance = 0.1 float hledane = 2.6 float s_cim = 2.6 if ( (hledane >= (s_cim - tolerance)) and (hledane <= (s_cim + tolerance)) ) jistě si už domyslíš jak udělat větší nebo menší než s tolerancí Zahadný problém v Delphi - cestmir - 14. 5. 2015 Ako máš deklarovanú premennú Ref? Double? StrToFloat() totiž podľa http://delphi.about.com/library/rtl/blrtlStrToFloat.htm vracia Extended, čo je 80b float, ktorý sa pri priradení do 64b zaokrúhli a následne už jedno z >= && <= neplatí (tam sa zase ten Double padne na 80b a porovnajú sa 80b hodnoty). 2,6 má totiž v dvojkovej sústave nekonečný desatinný rozvoj, takže z princípu nemôže byť reprezentované exaktne. 2,5 má konečný. V každom prípade ale platí, čo ti už napísali predrečníci, FP treba porovnávať vždy na rozsah, nie na rovnosť. Iná možnosť, ak sú hodnoty v tom def. súbore zapísané v zaokrúhlenom desatinnom tvare, a potrebuješ hľadať len na prostú zhodu, je hľadať pomocou regulárneho výrazu (na spôsob "^\s*Re\s*=\s*0*2,60*"), napr. pomocou niektorej mutácie grep-u a nechať si vyplúvať vhodný kontext pred/za výskytom. Zahadný problém v Delphi - antonio - 16. 5. 2015 Moc dík kluci, tak to vidím na sprosté obejití ±0,001. Zahadný problém v Delphi - antonio - 23. 5. 2015 Teď si zas pro změnu už delší dobu lámu hlavu jak by šlo přepsat: Kód: if key=vk_return then begin
if Sender=Edit1 then Edit2.SetFocus;
if Sender=Edit2 then Edit3.SetFocus;
end;na case. Rozhodně tohle funguje jen pro přeskočení z Edit1, pak už ne: Kód: if key=vk_return then case (Sender as TEdit).Tag of
1: Edit2.SetFocus;
2: Edit3.SetFocus;
end;Taky by mě zajímalo jak to udělat na .Name. Kód je v Edit1KeyDown a Edit2 z Object Inspectoru v OnKeyDown na něj odkazuje. PS: Už jsem tak zblblej, že po dopsání tohodle textu jsem zmáčknul Ctrl+F9.
Zahadný problém v Delphi - Hazys - 23. 5. 2015 Pokud událost onKeyDown chytáš z objektu Edit1, logicky bych čekal, že z objektu Edit2 nic nevyleze, když z něj událost nepochází. Zkus událost chytat z vyšší instance, třeba z Formu. PS: Nejsem odborník na delphi, jen občasný uživatel opensource konkurence - Lazarus-u Zahadný problém v Delphi - The_P - 24. 5. 2015 No, pokud vim Delphi a la Pascal neumi string v CASE, v Ccku se to delalo pomoci trebas strcmp() v kazdem bloku casu namisto abys tam dal cisla. Co jsem googlil, jedna z moznosti (ale ne elegantni zrovna): Kód: Case StrIndex('SomeName', ['bobby', 'tommy', 'somename']) of
0: ..code.. ;//bobby
1: ..code..;//tommy
2: ..code..;//somename
else
ShowMessage('error');
end.Coz ale diky tomu ze stejne si musis dat na indexy pozor je takove nanic. Myslim ze ten IF/ELSEIF bude v tomhle lepsi v prehlednosti. Trebas nekdo se skutecnou zkusenosti poradi lepe ;/ PS: Jeste mne napadlo, pokud dokazes zjistit name, ty indexy jdou za sebou a dokazes ten setFocus zavolat na jakemkoliv jmenu, asi by bylo lepsi udelat to ciste programove s tim, ze inkrementujes to cislo v nazvu no ne? Pripadne pokud jsou tam nepravidelnosti, udelat si mapovaci tabulku (Jmeno1 => Jmeno2, Jmeno2 => JineJmenoX) a pak jen malym kodem dole to zpracovat. Ovsem tohle uz jen spekuluju, jak je tohle v delphi pohodlne fakt netusim. Ciste pro inspiraci... |