Zdravím, chtěl bych se zeptat , jestli někdo neznáte nějakou assemblerovskou knihovnu pro výpočty v plovoucí řádové čárce. Případně i pro pevnu řádovou čárku.
Ideální by byla BSD licence , nebo LGPL
Děkuji za info , Martin.
administrator: přejmenováno z "Knihovna pro AVR FloatingPoint"
Ta celočíselná aritmetika v aplikačních poznámkách je v asm.
S pevnou ř. čárkou se to dělá přesně jak píšeš
Později, až ti něco nebude stíhat, dojdeš i na to, že je vhodný upravit výpočty pro dvojkovou soustavu - např. místo procent 1/100 použít 1/128 a zvýšit základ. Výsledek je pak stejný jako u procent, jen výpočet je rychlejší.
Právě tenhle binární způsob mě trochu děsil , jako že nemám 0.2 ale třeba 0.256 takže potom převod, třeba na znaky pro USART bude (pro mně) hůř pochopitelnej. Tyhlety soustavy, to není zrovna můj šálek kávy, ale co , bojovat se musí .
Celočíselně sčítat a odčítat by měl bejt minimální problém , každopádně kouknu do těch aplikačních poznámek, případný rozšíření třeba na 64 bitů by taky mohlo jít celkem snadno .
Ten převod na znaky je ještě jednodušší než u integeru. Když máš např. číslo 0b01000000 reprezentující hodnotu 0,25 převést na znaky, uděláš to postupným násobením 10 instrukcí MUL. V horním byte dostaneš dekadickou cifru za desetinou čárkou a v dolním zbytek, který opět vynásobíš 10. Tímto postupem získáš postupně všechny cifry od nejvyšších řádů až po nejnižší.
Pokud by si chtěl algoritmus na float, není nic jednoduššího než založit projekt v Céčku, napsat jediný řádek s operací float, přeložit a podívat se do listu na výsledek v asm.
Dobře, prozkoumám to.
ASM je mi bližší než C , ani nevím proč, možná proto, že jsem v něm kdysi sem tam něco dělal na ZX Spectru , dokonce i něco jako multitasking. Je mi jasné, že v céčku se vyvíjí rychleji ale když jsem našel jeden příklad pro řízení spínaného zdroje a kód v C měl po přeložení cca 1kB a v ASM asi 400 B byl jsem překvapen a to tak, že hodně , vždycky jsem myslel, že C bude hodně optimalizované a výsledek bude ± podobný.
Co je na něm tak složitého? Číslo, které jsi uvedl, můžeš zapsat jako 0x00FF2^(-8). Vynásobím např. 2, kterou mohu zapsat takto: 0x02002^(-8). Jde o exponenciální tvar, kde platí, že při násobení se násobí mantisy a exponenty se sčítají.
Exponent 2 představuje pozici binární tečky se kterou se u fixed point nemusíme zabývat, takže celé násobení je úpně totožné jako u (unsigned) int. Pozice binární tečky je rozhodující pouze při převodu do dekadické soustavy.
Pro zajímavost: exponent nemusí být vždy 2, může to být zcela libovolné číslo, třeba Ludolfovo. Klidně i 10. Na tom pak bude záležet i numerická přesnost. Né každé číslo lze zapsat, takže se musí zaokrouhlovat na nejbližší.
Jako příklad uvedu deklaraci proměnné H, která bude reprezentovat vzálenost s přesností na 0,001 m. Nepotřebuji floating ani fixed point, stačí zapsat:
unsigned int H; // vzdálenost v mm
Mohu ji zrovna tak interpretovat jako H*10^(-3) v metrech. Takže je to jen záležitost převodu do dek. soustavy.
Nevím, zda v Céčku existuje fixed point, ale z výše uvedeného je zřejmé, že by byl zcela zbytečný a v pohodě jej nahradí int.
Tak… A ernie má po zábavě. Takovej krásně dlouhej a pomalej podprogram mohl vytvořit a nic z toho nebude Teď jen upraví uint16*uint16 a je hotovo.
V C to není, taky to vždy řeším dostatečně dimenzovaným uint.
Za určitých okolností by se mu mohl snížit dopad ořezávání, protože bude odstraňovat pouze 1 msB (a 1 lsB) místo dvou msB u intu, jinak to ale asi žádný zvláštní význam nemá.
Hmm. Moc dlouho jsem do toho vejral, ernie byl rychlejší