Få bättre precision på double

Elektronikrelaterade (på komponentnivå) frågor och funderingar.
Christian
Inlägg: 86
Blev medlem: 3 november 2003, 22:54:49

Få bättre precision på double

Inlägg av Christian »

Försöker få så bra precision på en double variabel som möjligt, men kommer inte nära nog..
Använder en 8bitars PIC..
Har ställt in Double float inställningen i MpLab till 32 bit men det kanske finns något mer jag kan göra?

Här är uträkningen:

Kod: Markera allt

   double x=0.0;
	char vector1[] = {'5','5','3','5','.','4','4','1','5'};
	char vector2[] = {'0','0','0','0','0','0','0','0','0'};
	vector2[0] = vector1[5];
	vector2[1] = vector1[6];
	vector2[2] = vector1[7];
	vector2[3] = vector1[8];
	vector2[4] = vector1[9];
	x = (double)(atol(vector1)/100) + ((double)(atol(vector1)%100) + atof(vector2)/100000.0)/60.0;  
   printf("x is %f", x); 
Outputen blir: x is 55.584068

Om jag slår det hela på en miniräknare: 55.59069167 <== Vill komma så nära detta värdet som möjligt

Några förslag?

Do you have any other suggestions?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Få bättre precision på double

Inlägg av sodjan »

Vad används värderna till ?
Alltså, vad representerar de i verkligheten ?
Och vad "gör" beräkningen som sådan ?
I just det visade fallet så är det ju hårdkodade invärden,
så hela beräkningen är lite onödig, du kan skriva in vilket
resultat du vill direkt i koden... :-)
Användarvisningsbild
ahlsten
Inlägg: 659
Blev medlem: 12 november 2005, 00:24:14
Ort: Uppsala

Re: Få bättre precision på double

Inlägg av ahlsten »

Eftersom PICen du använder saknar FPU (chansar jag på) så används ett mjukvarubibliotek för ändamålet... så en variant vore kanske att använda ett annat bibliotek, nått IEEE 754 kanske.
Batman
Inlägg: 97
Blev medlem: 11 december 2010, 15:05:42
Ort: Umeå

Re: Få bättre precision på double

Inlägg av Batman »

Kod: Markera allt

   double x=0.0;
   char vector1[] = {'5','5','3','5','.','4','4','1','5'};
   char vector2[] = {'0','0','0','0','0','0','0','0','0'};
   vector2[0] = vector1[5];
   vector2[1] = vector1[6];
   vector2[2] = vector1[7];
   vector2[3] = vector1[8];
   vector2[4] = vector1[9];
   x = (double)(atol(vector1)/100) + ((double)(atol(vector1)%100) + atof(vector2)/100000.0)/60.0;  
   printf("x is %f", x); 
Strängarna vector1 och vector2 är inte noll terminerade, då kan man få konstiga resultat då atol/atof inte vet när strängen slutar.
Du läser från vector1[9] som är odefinierad, då vector1 innehåller endast 9 element. Detta kan ge konstiga resultat.
Användarvisningsbild
AndLi
Inlägg: 18271
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: Få bättre precision på double

Inlägg av AndLi »

Jag försökte få fram det värdet du knappat på miniräknaren, men får bara fram det värde som ditt program ger dig...

Vektor1 vill du ska vara "5535.4415"
Och man kan gissa att din strängkopiering är till för att få vektor2 att bli "4415"

Är det medvetet att du använder atol på vektor1?

X = (5535/100)+((5535%100)+(4415/100000.0))/60;
Första parantesen är inga flyttal med alltså blir det 55 (du castar dock resultatet till en double...)
Andra parantesens första innerparantes blir 35
I sista parantesen har du använt atof men vektor 2 är ett heltal, men eftersom du vill ha ut ett flyttal kan det vara en bra säkerhet för att kompilatorn inte ska få för sig något.
Resultatet blir 0.04415

Vi får då alltså
X = 55 + (35 +0.04415)/60
Vilket är 55.5840691666667

Så det verkar faktiskt som du har haft tur och fått in en nolla efter sista siffran i vector1.
Varför skriver du inte:
char vector1[] = {"5535.4415"};
char vector2[] = {"000000000"};
Då får du dina nolltermineringar per automatik.

edit: ändra ett / till ett + i sista uträkningen
Senast redigerad av AndLi 5 juli 2011, 20:05:32, redigerad totalt 1 gång.
Användarvisningsbild
AndLi
Inlägg: 18271
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: Få bättre precision på double

Inlägg av AndLi »

Om vi då ändrar alla atol till atof så får vi istället ett uttryck som ser ut:
X=55.354415+(35.4415+0.04415)/60
Men detta får jag(okej OO) till 55.9458425, så vad slog du på miniräknaren?
Användarvisningsbild
AndLi
Inlägg: 18271
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: Få bättre precision på double

Inlägg av AndLi »

Och mitt egna förslag att atof skulle lösa det funkar inte, då modulo (%) opperatorn inte funkar på flyttal.

Visar ju hur ofta jag använder flyttal, men oftast har de inget att göra i en µC
Nerre
Inlägg: 27217
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Få bättre precision på double

Inlägg av Nerre »

Jag tror ditt problem är formeln du använder.

Nu är jag inte helt 100 på åt vilket håll man ska tänka, men jag tror det är så att du ska försöka "bryta ut" alla divisioner och ta dem sist, för att inte tappa decimaler. Eller vänta nu, för flyttal kanske det inte spelar nån roll...?

I skolan fick man ju i alla fall lära sig att räkna symboliskt så långt som möjligt och inte använda miniräknaren för långa formler eftersom småfelen ackumulerades för varje steg.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Få bättre precision på double

Inlägg av sodjan »

Den absolut intressantaste frågan är dock fortfarande vad som *igentligen*
ska göras. Det jag frågade efter i förstasvaret. Innan vi vet det så är
resten ganska ointressant.
Batman
Inlägg: 97
Blev medlem: 11 december 2010, 15:05:42
Ort: Umeå

Re: Få bättre precision på double

Inlägg av Batman »

AndLi skrev:Jag försökte få fram det värdet du knappat på miniräknaren, men får bara fram det värde som ditt program ger dig...

Vektor1 vill du ska vara "5535.4415"
Och man kan gissa att din strängkopiering är till för att få vektor2 att bli "4415"
Provade att sätta vector2 till "44150", då får jag det svar TS vill ha: 55,590691666666666666666666666667
Så det har nog med hur TS tror att stränghanteringen ska funka.
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Få bättre precision på double

Inlägg av bearing »

Eftersom att Christian tidigare skrivit om GPS gissar jag att det här handlar om behandling av GPS-koordinater.
Batman
Inlägg: 97
Blev medlem: 11 december 2010, 15:05:42
Ort: Umeå

Re: Få bättre precision på double

Inlägg av Batman »

sodjan skrev:Den absolut intressantaste frågan är dock fortfarande vad som *igentligen*
ska göras. Det jag frågade efter i förstasvaret. Innan vi vet det så är
resten ganska ointressant.
Jag tycker det är viktigare att man går till botten med de fel som finns i koden. Då stränghantering är något som behövs när man programmerar c.
Nerre
Inlägg: 27217
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Få bättre precision på double

Inlägg av Nerre »

bearing skrev:Eftersom att Christian tidigare skrivit om GPS gissar jag att det här handlar om behandling av GPS-koordinater.
Ja, det ser ju ut som omvandling till decimalgrader.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Få bättre precision på double

Inlägg av sodjan »

OK. Det finns ofta metoder med kombinationer av tabelluppslagning
och interpolation som i alla fall ofta går betydligt snabbare än att
försöka göra råa beräkningar rakt av.

> Jag tycker det är viktigare att man går till botten med de fel som finns i koden.

Absolut. Men "felet" kan vara att det är fel motod... :-)
Nerre
Inlägg: 27217
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Få bättre precision på double

Inlägg av Nerre »

Det som ska göras är väl att konvertera en vinkel (latitud eller longitud) som kommer i ascii-format som grader.minuter till grader med decimaler (i form av en float?).

Fast frågan är om en float är det vettigaste för att representera latitud och longitud? Jag undrar om inte fixed vore mycket vettigare?

Fördelen med float är ju den stora "dynamiken", men latitud/longitud är ju i princip bara mellan 0 och 180 och man har ju inget behov av större precision vid små vinklar än större vinklar.
Skriv svar