Hodilo by se něco podobného volat in a MCU? Kdysi jsme dělali ve fixed point formátu, dokonce na to měla Motorola 68011 nějakou podporu při násobení a dělení. A samozřejmě většina věcí se musela předpočítávat do EPROM, tedy kromě tabulky násobení. Na to nezbylo místo (64 kB EPROM jestli se nepletu, plus nějaký kilobajt na BUFALLO).
Záleží, o jaký čip se jedná :-). Pokud je to osmibitový šváb s pár kB FLASH, tak to může být problém, protože (a teď tedy trošku hádám) SW implementace bfloat16 nebo half-float nebude o moc jednodušší, než klasická implementace float/single. Spíš by to chtělo něco jednoduššího, bez podpory denormalizovaných čísel, NaN a nekonečen - tím se ušetří spousta podmínek a speciálních případů.
https://github.com/DW0RKiN/Floating-point-Library-for-Z80
Softwarova implementace bfloatu (s prehozenou pozici znamenkoveho bitu), binary16 (half) a formatu Daniela A. Nagyho (seee eeee mmmm mmmm) pro procesor Z80. Bez te podpory denormalizovanych cisel, NaN, nekonecen a presne nuly. Takze ani NaN nemuze po zadne matematicke operaci nastat. Fce jen vraci carry pokud je vysledek mimo rozsah a nasledne vrati maximalni nebo minimalni pripustnou hodnotu. Jsou tam i nahledy pri pouziti jednotlivych formatu v raytracingu. Takze si lze udelat predstavu o presnosti a casove narocnosti (cca 100x rychlejsi jak raytracing v basicu ZX Spectra) i o velikosti kodu s pomocnymi tabulkami.
13. 2. 2020, 05:18 editováno autorem komentáře
Ještě se zeptám - potřebujete pouze výpočty nebo i zobrazení hodnot (na nějakém připojeném displeji). Ten kód pro zobrazení bývá velký. Pokud není potřeba, tak například pro M0 (ok, to není osmibit, ale cenově dostupný 32bit ARM) existuje https://www.quinapalus.com/qfplib.html
; (a-b)^2 = aa-2ab+bb
; (a+b)^2 = aa+2ab+bb
; (a+b)^2-(a-b)^2 = 4ab
; ((a+b)^2-(a-b)^2)/4 = a*b
; ((a+b)/2)^2-((a-b)/2)^2 = a*b // plati jen diky trikum s lichymi a sudymi cisly
; 1.aaaaaaaa * 1.bbbbbbbb = // kde 1. je neukladany jednickovy bit
; (1+a)*(1+b) =
; ((1+a+1+b)^2 - (1+a-1-b)^2)/4 =
; ((2+a+b)^2 - (a-b)^2)/4 =
; (4 + 4*(a+b) + (a+b)^2 - (a-b)^2)/4 =
; 1 + a + b + ((a+b)^2 - (a-b)^2)/4 =
; 1 + a + b + ((a+b)/2)^2 - ((a-b)/2)^2
Pokud mantisa bez neukladaneho bitu je 8 bitova tak tabulka pro nasobeni ma 256 sestnactibitovych hodnot.
13. 2. 2020, 04:42 editováno autorem komentáře
Pravdivost pri vylouceni NaN a -NaN.
x == (int)(float) x
Obecne ne. Int je typicky 32 bit, float je 32 bit a obsahuje znamenka a exponent, jak to stoji v clanku. Napr. INT_MAX neprojde, jsou to binarne jenom jednicky az na prvni bit a to se do floatu nevleze.
Ano pro architektury se sizeof(int) <=2, jako treba stare 16 bity.
x == (int)(double) x
Ano, mantisa ma u doublu 52 bit, tam se int vleze.
f == (float)(double) f
Ano, jde jenom o rozsireni typu.
d == (float) d
Ne, 64 bitovy typ se do 32 bit nevleze. Volme treba INT_MAX z prvniho prikladu.
f == -(-f);
Ano, znamenka jsou ulozena samostatne.
2/3 == 2/3.0
Ne, celociselne deleni neni rovno deleni floatu: 0 != 0.66666.
d < 0.0 ((d*2) < 0.0)
Ano, double a floaty by meli pretict do nekonecna.
d > f -f > -d
Ano, kdyz to tedy neni chytak, tak floaty a doubly jsou symetricke kolem 0 diky znamenku.
d * d >= 0.0
Ano, znamenko se pocita jako xor znamenek. Vyjimkou by byl NaN, ale ty jsou vylouceny.
(d+f)-d == f
Ne, treba kdyz d+f je prilis velke a je z toho nekonecno , pak nekonecno minus cislo bude vzdy nekonecno. Neplati treba f=FLT_MAX, d=DBL_MAX.
Velmi dobrá otázka :-) Co vím, tak navíc nebudou platit ty dvě podmínky, které počítají s tím, že nula má znaménko. To se u -ffast-math ignoruje (nebo přesněji řečeno ignorovalo). Ale je docela dobře možné, že přestane platit ještě něco dalšího (na nekonečna jsme se neptali, ale možná ani nebude platit podmínka výpočtů pro Inf-Inf, Inf/Inf atd.)