

Pretypovanie real na integer mimo trunc - Delphi
Dobrý deň, priatelia, vedeli by ste mi, prosím, dať kvalifikovanú odpoveď na otázku, ako v Delphi 6 spoľahlivo pretypovať real alebo extended na integer? Vždy ma učili používať na to funkciu trunc, ktorá by vraj mala vrátiť celočíselnú časť z reálneho čísla. Prax mi však ukázala, že táto definícia nie je celkom správna. Neraz sa mi stalo, že moja aplikácia nepracovala celkom správne a často bol na vine práve príkaz trunc, ktorý vrátil nižšiu hodnotu najmä vtedy, ak parametrom bol nejaký výpočet alebo záporné číslo. Práve teraz tu mám relatívne jednoduchý prípad - užívateľ do editačného poľa vpíše reálne číslo, ktoré potom má byť vynásobené 1000 a ďalej už spracovávané ako celé číslo. Ak však do editačného poľa vpíšem -16.275 a urobím nasledovné operácie:
var x,y:real;i:integer;
x:= strtofloat(ansireplacetext( edit2.text,'.',',')); // prevediem si obsah edit pola na real - výsledok je -16,275;
y:=x*1000; // vynásobím 1000 - výsledok je -16275 v premennej typu real;
i:=trunc(y);
výsledkom nie je -16275 ale -16274. Takéto situácie sa mi stali už viackrát, preto hľadám spôsob, ako skutočne spoľahlivo pretypovať real na integer bez ohľadu na to, či je číslo kladné alebo záporné a dostať naozaj tú časť čísla, ktorá je pred desatinnou čiarkou. Vďaka.
pme: vďaka, chyba bola skutočne v argumente typu real, pričom mal byť extended. Teraz to už naozaj pracuje ako má. Ja som bol vždy vedený k tomu, aby som používal úsporné typy teda napr aj word alebo bite keď je zbytočné použiť integer a tak som aj v mojom projekte použil real namiesto extended, lebo som mal za to, že real je vzhľadom na počet použitých bitov úspornejší a ja sa hodnotami určite pohybujem v rozsahu -180000.000 až 180000.000 s počtom desatinných miest max 3, aj keď samozrejme chápem že sú obsadené aj ďalšie miesta za desatinnou čiarkou, ale pre prácu ich nepotrebujem a ignorujem.
MM: S tou raketou vystrelenou na mesiac a pristátim kilometer vedla si v podstate trafil kliniec po hlavičke, lebo aplikácia, na ktorej pracujem, prezerá mapu, takže tie čísla sú vlastne gps súradnice. Mám negraficky lineárne spracovanú databázu gps pozícií takmer celého sveta, pričom rozlíšenie je relatívne velké - až 3 desatinné miesta. Nemám ale jednotlivé body, ale plochy, určené lavým dolným a pravým horným rohom, takže napr 48.120,17.060 až 48.159,17.099 je Bratislava - Staré mesto. Pohybom šípky sa v podstate zvyšuje a znižuje latitúda a longitúda, čo by sa za normálnych okolností malo diať tak, že súradnice, zapísané v premenných typu real alebo extended by mali zvyšovať a znižovať hodnotu a teda by som k nim mal pripočítavať a odpočítavať niekde na úrovni tretieho miesta za desatinnou čiarkou. To ale v praxi práve spôsobuje tú výchylku, o ktorej si písal, po pár desiatkach či stovkách operácií si už niekde úplne inde, preto to robím tak, že súradnice sú vynásobené 1000 a samotný pohyb je rátaný tesne za desatinnou čiarkou. Tak sa posunieš napr zo 48120.000000 na 48159.7872, čo teraz treba vyhodnotiť a oznámiť, čo sa na danej súradnici nachádza. Keďže to za čiarkou je len pomocná hodnota pre rátanie pohybu a rozlíšenie mapy mám len na 3 desatinné miesta gps, to za čiarkou dám preč a výsledné 48159 zodpovedá latitúde 48.159 (rovnako tak aj s longitúdou). A práve tu je zaokrúhlenie kontraproduktívne, lebo kým 48.159 je ešte Bratislava staré mesto, 48.160 je už niečo iné. Preto som sa potreboval vyhnúť zaokrúhleniu a ak trunc vracalo chybný výsledok, tak som sa geograficky naozaj ocitol o kilometer inde.
Ešte raz vďaka všetkým.
Ani extended neni spravne. (mozu tam vzdy vznikat chyby pri tom zaokruhlovani, zavisi to od zadaneho cisla)
BTW. vcera som aj hladal ze ci nahodou pri extended sa neuklada binarne inac, a ne, aspon podla toho co som nasiel specifikacie. Takze aj tam ti vznikyju chyby zapisu, neviem zhlavy preco to konkretne cislo zaokruhli u extended na to vyssie cislo (nechce sa mi to prevadzat rucne ani instalovat nejake delphi kvoli tomu :) ale moze to suvisiet len s tym konkretnym cislom a ine moze byt zas blbo.
Pri praci s plavajucou ciarkou musis musis vzdy mysliet aj na chybu zapisu a vypoctu, a pri konverziach sa to musi vzdy zaokruhlovat aspon s prihliadnutim na maximalnu moznu odchylku po tom vypocte, t.j. priratat si tam aspon tu ocakavanu max. chybu, apod.
Napr. tuto mas viac pokecu, ak by ta to nahodou zaujimalo. Vidiet tam jasne ze aj extended ma chyby, samozrejme.
articles-floats.html
Napr. zaujimave je aj toto
To by vysvetlovalo ze preco nahodou toto cislo v extended nahodou zaokruhluje tak, ale bude to zavisiet od zadaneho cisla (skusaj si rozne cisla alebo si urob program aby ti preskusal vsetky mozne cisla a vypisal ked to pri niektorom bude nespravne, a napis jak si dopadol :)