Fixed point-problem

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
LHelge
Inlägg: 1772
Blev medlem: 2 september 2007, 18:25:31
Ort: Östergötland
Kontakt:

Re: Fixed point-problem

Inlägg av LHelge »

jag har koll på vad fixed point är, kanske borde varit lite tydligare med att korken har skickat sin kod till mig. mycket riktigt är fixed bara en typedef av en 32 bitars int. jag tycker egentligen inte att det är konstigare än att man skriver skruv på en kaffeburk för att det inte ska vad några tveksamheter om vad man förvarar i den.

det jag ville åstadkomma var bara att på enklast möjliga sätt klämma in korkens kod i en miljö där float används normalt sett, för att testa om det GÅR att använda fixed point där.

edit: (nu har jag klivit av bussen och kan skriva på en vanlig dator)
Som jag skrev i texten ovan mitt kodexempel så är fixed en 32 bitars int med 18 bitar fractional
sodjan skrev:

Kod: Markera allt

float f = 1.2345;
fixed fix = (fixed)f*262144.0f; // 2^18 = 262144
borde vara något i stil med

Kod: Markera allt

float f = 1.2345;
int fix = f * 262144; // 2^18 = 262144
Eventuellt om konstanten behöver castas till float för att undvika
att "f" castas till en int innan multiplikationen. Jag kan inte C...
Borde väl i detta fall vara exakt samma sak.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Fixed point-problem

Inlägg av sodjan »

> Borde väl i detta fall vara exakt samma sak.

Ja, det beror ju på vad "fixed" betyder. Jag tror inte att det framgick.
Om det bara är en omskrivning/typedef av "int", så visst... :-)
Men vad är fördelen med det ?

> ...än att man skriver skruv på en kaffeburk

I detta fall var det mer som att skriva "diverse-burk" på en kaffeburk.
"fixed" säger inte mer än "int" om vad den representerar eller innehåller.
Det är bara ett annat namn på samma burk.

Men om det ska vara meningsfullt att hitta på en ny typ över huvudtaget
så är ett namn som "fixed_32_18" eller liknande bättre. Hur skilljer man
annars på olika "fixed" med olika stora decimal delar ? Inte för att det ju
spelar någon roll om de ändå alla är typedef's på int, men i alla fall...

> ...i en miljö där float används normalt sett, för att testa om
> det GÅR att använda fixed point där.

Antingen har man gjort hemläxan från början och då används float p.g.a
att det just inte går att använda en fixed. Eller så visste man inte riktigt
vad man höll på med och då fungerar ofta även fixed point... :-)

Om det går eller inte har mer med de aktuella variablernas dynamiska
område att göra än något annat.
Användarvisningsbild
LHelge
Inlägg: 1772
Blev medlem: 2 september 2007, 18:25:31
Ort: Östergötland
Kontakt:

Re: Fixed point-problem

Inlägg av LHelge »

Precis, i det här fallet var jag osäker om det skulle fungera med fixed, och körde på float direkt för att spara tid. Prestandamässigt var det inga problem. Koden snurrar på 3-4 ggr snabbare än vad som behövs på en dsPIC. Men nu ska det eventuellt över till en annan processor och det skulle kunna vara intressant att optimera.

Det är just det dynamiska omfånget som oroar mig. Det handlar om ett kalman-filter.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Fixed point-problem

Inlägg av sodjan »

Tid är en ofta underskattad resurs... :-)
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Fixed point-problem

Inlägg av blueint »

Vad används kalman filtret till? ;)

Annars är det väl läge att utöka variabellängden?
Användarvisningsbild
LHelge
Inlägg: 1772
Blev medlem: 2 september 2007, 18:25:31
Ort: Östergötland
Kontakt:

Re: Fixed point-problem

Inlägg av LHelge »

Det är detta:
http://www.elektronikforumet.com/forum/ ... =3&t=46458

Ska testa om det funkar först, klarar C30-kompilatorn av att jobba med 64-bitars int? Kommer det vara effektivare med 64-bitars fixed point än 32-bitars floating? Klarar AVR-kompilatorn (vilken använder man? GCC?) av 64-bitars int?
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: Fixed point-problem

Inlägg av snigelen »

AVR-GCC klarar 64-bitars heltal, men det blir väldigt segt. Klart långsammare än float. float är väl bara marginellt långsammare än 32-bits heltal.

Edit: Wow 2^8:e inlägget :D
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Fixed point-problem

Inlägg av jesse »

mycket riktigt är fixed bara en typedef av en 32 bitars int.
Jaja, då förstår jag varför jag inte kände till typen :D
Jag trodde ni hade använt något slags vedertaget standardbibliotek för fixtal eller liknande, som jag inte kände till.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Fixed point-problem

Inlägg av Korken »

Ojojoj vad mycket ni hinner skriva på så kort tid! :)

Det var dåligt av mig att inte förklara vad "fixed" är.
Jag har gjort en typdef så jag vet vilka ta som är fixed point och vilka som inte är det (lättare att hålla koll).

Kod: Markera allt

#define FRAC_PART	18
#define ONE			(fixed)(1<<FRAC_PART)
#define INT2FP(x)	(x << FRAC_PART)

typedef int fixed;
Varför jag skriver eget fixed point bibliotek är för att jag vill förstå och kunna det bättre och det är riktigt kul att leka med! :)
Jag använder min fixed point kod i mitt Kalman-filter och PID-regulator till min Quadrocopter.

LHelge har fått min (inte än färdiga) kod så han kan testa och se om det blir någon prestanda skillnad mot floating point.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Fixed point-problem

Inlägg av Korken »

Jag ska utöka detta lite till tror jag, fast det har mer med kodning att göra än fixed point, även om det är kopplat.

Just nu har jag ju funktioner för fixed point multiplikation och division (fMul och fDiv), men går det att få kompilatorn att förstå om jag har tex:

Kod: Markera allt

fixed a, b, c;
a = b * c;
Så använder den min funktion (fMul) då de är "typade" som fixed istället för att använda den vanliga multiplikationsfunktionen?
Så man slipper skriva fMul/fDiv över allt, för det blir väldigt snabbt väldigt grötigt.

Är detta möjligt?
monstrum
Inlägg: 620
Blev medlem: 13 januari 2005, 05:38:32
Ort: Göteborg

Re: Fixed point-problem

Inlägg av monstrum »

I C++ går det, men standard C klarar inte detta (overloading).
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Fixed point-problem

Inlägg av sodjan »

OK, jag måste fråga...
Vad är det för skillnad på din fMul och en vanlig integer multiplikation ?
monstrum
Inlägg: 620
Blev medlem: 13 januari 2005, 05:38:32
Ort: Göteborg

Re: Fixed point-problem

Inlägg av monstrum »

Kan inte tala för hur TS har gjort, men man måste ju skifta resultatet också (efter multiplikationen). Resultatet blir ju annars inte samma format. 16.16 * 16.16 blir ju 32.32, eller 0.32 ifall man bara har 32 bitars tal, detta måste hanteras på något sätt.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Fixed point-problem

Inlägg av sodjan »

Jag är fortfarande intresserad av vad det är för skillnad... :-)

> ...men man måste ju skifta resultatet också

Ja, som vid all multiplikation.

Ett par exempel. Vanlig binär integer multiplikation :

101 x 101 = 11001 (5 x 5 = 25 decimalt)

Om vi antar ett 2.1 fixed point format så blir multiplikationen ovan
exakt likadan men *tolkningen* av resultatet blir lite annorlunda :

10.1 x 10.1 = 110.01 (2.5 x 2.5 = 6.25 decimalt).

Eller ett 1.2 format :

1.01 x 1.01 = 1.1001 (1.25 x 1.25 = 1,5625 decimalt (1 + 1/2 + 1/16).

Så det jag menar är att det inte i grunden är någon skillnad. Det jag var
nyfiken kring är om det enbart är hanteringen av kommat som skiljer ?
Å andra sidan så finns det ju inget kommat annat än vid presentation av
värdet på LCD, skärm eller liknande. Kommat är aldrig lagrat tillsammans
med värdet i alla fall (eller borde inte vara det i alla fall, i så fall har man
nog tänkt lite fel).

> 16.16 * 16.16 blir ju 32.32

Det är samma *multiplikation* som 32 x 32 = 64. Att man har tänkta decimalkomman
ändrar inget, de ingår inte i *multiplikationen* som sådan. Och även vid ren integer 32x32
mult så måsta man bestämma vad man ska göra med 64 bitars resultatet, ingen skillnad.

Hur menar du att man skall "skifta" 32.32 resultatet så att det blir 16.16 (om det
är det som du menar med "samma format") ? Om man vill ha ett 32 bit resultat så
är en 32 bit integer den ända tänkbara. D.v.s alla decimaler trunkeras (eller avrundas).
Eller så vet man i förväg något om de ingåenda värderna som gör att man vet att man
inte kommer att nå max-värdet, då kan man även trunkera en eller flera av de
höga bitarna och behålla mostsvarande antal av decimalbitarna, men som sagt, det
kräver lite specifik kunskap om de ingånde värderna. Om man t.ex vet att heltalsdelen
aldrig går över 16 bitar, så kan man ta "mittenbitarna" av 16+16.16+16 och göra det
till det nya 16.16 resultatet av multiplikationen. D.v.s kasta de högsta 16 bitarna
av heltalsdelen och de *lägsta* 16 bitarna av decimaldelen.

Det är samma "problem" som att multiplicera två 2-siffriga decimal tal och
säga att det aldrig får bli > 99 (eftersom det ska vara "samma format").


Eller för att jämföra med ett par decimala exempel :

123 x 456 = 56088
12.3 x 45.6 = 560.88
1.23 x 4.56 = 5.6088

Fortfarande är det i grunden exakt samma multiplikation, det är bara placeringen
av decimalkommat (som inte ingår i multiplikationen som sådan) som skiljer. Det
fixar men i efterhand. Om man ställer upp det med papper och penna så är det
ingen skillnad mer än i slutet då kommat ska sättas rätt, men det är, som sagt,
inte del i själva multiplikationen som sådan.

Aja, som sagt, bara lite nyfiken, och generellt intesserad av matte... :-)
monstrum
Inlägg: 620
Blev medlem: 13 januari 2005, 05:38:32
Ort: Göteborg

Re: Fixed point-problem

Inlägg av monstrum »

Ja självklart är det som du beskriver. Kommat lagras ju inte. Dock så är det ofta opraktiskt ifall man inte kan ta resultatet från en multiplikation och använda denna precis som vilket annat tal som helst.

T.ex. så har man en indata-värde och en multiplikator, t.ex. i ett filter.
Det som ska beräknas är inval[0]*K[0] + inval[1]*K[1] + inval[2]*K[2], sedan skall alltihop skalas med F.
Om en rutin alltid ser till att resultatet har samma format som operanderna så är det väldigt smidigt att bara skriva. fMul( inval[0], K[0] ) osv. och sedan köra en fMul( result, F ).

Visst, man kan använda helt vanlig multiplikation direkt, men då flyttas ju det tänkta decimalkommat runt. Dessutom måste blir det antagligen överslag efter några få operationer ifall man inte skiftar ner och trunkerar bort lägsta bitarna.



Hur man skulle hantera 16.16 x 16.16 var bara ett exempel på ett ställe där man måste hantera det på något sätt. Kör man bara rätt av med multiplikation så tappar du ju så att säga bort hela heltalsdelen. Detta kanske är meningen, men knappast en generellt bra lösning. Då kanske man får skifta ner 8 bitar och därmed konvertera till 16.8 x 16.8.


Edit: Jag misstänker att du (Sodjan) egentligen är lite mer inne på flyttal, där kommaplaceringen inte är fixerad. Med fixpunkt vill man ju att komma alltid är på samma plats.
Senast redigerad av monstrum 8 maj 2011, 18:25:41, redigerad totalt 1 gång.
Skriv svar