Float - Hur många decimaler ska jag använda? 6, 7, 8 eller 9?

Permalänk

Float - Hur många decimaler ska jag använda? 6, 7, 8 eller 9?

Jag ska generera högprecision i float och detta ska skrivas in i en fil.
Float har inte samma precision som double, men jag måste använda float. Vad har float för maximal antal decimaler? Är det 7 stycken? Jag har hört 9 ibland.

Detta gäller ANSI C.

Permalänk
Medlem

Nu kan jag inte C, men ska du skriva det till en fil så skriver du väl objektet som det är?
Eller tänkte du skriva en string-representation av datan till fil, isåfall skriver du väl med den precision du vill ha?

Detta kanske hjälper dig? https://stackoverflow.com/questions/68660588/how-float-and-do...

Permalänk
Medlem

Jag tror inte ANSI C specificerar något särskilt format för flyttal, men i praktiken är det nog IEEE 754-formatet som används. Med det antagandet så blir det en jäkla massa decimaler då en single precision floating point kan representera talet 2^(-126) genom att sätta samtliga bitar i exponenten till 0 och sedan sätta mantissan till 1. Det exakta talet är 1.1754944e-38, så 45 decimaler bara där. Om jag inte räknat fel. Jag kan mycket väl ha räknat fel, det gjorde jag nämligen på försök nummer 1

Med det sagt, vad är det du försöker göra? Varför behöver du veta antalet decimaler för att skriva ett flyttal till fil?

Räknade ju givetvis fel
Permalänk
Medlem

Floating point betyder just att det inte finns ett fixt antal decimaler, utan det varierar med storleken på talet som ska representeras

Permalänk
Skrivet av SimpLar:

Jag tror inte ANSI C specificerar något särskilt format för flyttal, men i praktiken är det nog IEEE 754-formatet som används. Med det antagandet så blir det en jäkla massa decimaler då en single precision floating point kan representera talet 2^(-126) genom att sätta samtliga bitar i exponenten till 0 och sedan sätta mantissan till 1. Det exakta talet är 1.1754944e-38, så 45 decimaler bara där. Om jag inte räknat fel. Jag kan mycket väl ha räknat fel, det gjorde jag nämligen på försök nummer 1

Med det sagt, vad är det du försöker göra? Varför behöver du veta antalet decimaler för att skriva ett flyttal till fil?

Det jag ska göra är att jag ska spara float värden i en fil. Just nu har jag valt 9 decimaler.
Jag tänkte att "desto fler siffror, desto bättre". men det kanske kan bli tokigt också...

Permalänk
Medlem
Skrivet av heretic16:

Det jag ska göra är att jag ska spara float värden i en fil. Just nu har jag valt 9 decimaler.
Jag tänkte att "desto fler siffror, desto bättre". men det kanske kan bli tokigt också...

Om det blir tokigt eller inte beror ju helt på vad för data du ska spara....
Min favoritfråga, vilket problem försöker du lösa?
Och nej, problemet är inte "spara float värden i en fil"

Permalänk
Medlem
Skrivet av heretic16:

Det jag ska göra är att jag ska spara float värden i en fil. Just nu har jag valt 9 decimaler.
Jag tänkte att "desto fler siffror, desto bättre". men det kanske kan bli tokigt också...

Det är bara du själv som kan svara på hur många decimaler som är skäligt att lagra för datapunkten det gäller.

Visa signatur

Windows 11 Pro | Intel i7 8700 | ASUS Prime Z370-P | Corsair 16GB 3000MHz | ASUS GTX 1080 | Fractal Design Define S | Corsair RM750x | Hyper 212 EVO

Permalänk
Skrivet av Xcorp:

Om det blir tokigt eller inte beror ju helt på vad för data du ska spara....
Min favoritfråga, vilket problem försöker du lösa?
Och nej, problemet är inte "spara float värden i en fil"

Det jag ska göra är att jag har byggt en C-genererare som genererar en stor .h fil med massa statiska arrayer i.
Dessa värden har typ värderna 0.0002324 eller 0.000002342. Då tänkte jag om mer decimaler ökar precisionen eller inte.

Permalänk
Datavetare

Tror du frågar: hur många signifikanta siffror kan C float/double representera.

Svaret är lite lurigt,

32-bit float kan minst hålla 6 signifikanta siffror men det är nästan alltid minst 7 och kan vara upp till 9 för specifika tal.
64-bit float kan minst hålla 15 signifikanta siffror men det är nästan alltid minst 16 och kan vara upp till 21 för specifika tal.

Verkar handlar om 32-bit float här, så 6, 7 eller 9 beroende på vad du vill uppnå

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Skrivet av Yoshman:

Tror du frågar: hur många signifikanta siffror kan C float/double representera.

Svaret är lite lurigt,

32-bit float kan minst hålla 6 signifikanta siffror men det är nästan alltid minst 7 och kan vara upp till 9 för specifika tal.
64-bit float kan minst hålla 15 signifikanta siffror men det är nästan alltid minst 16 och kan vara upp till 21 för specifika tal.

Verkar handlar om 32-bit float här, så 6, 7 eller 9 beroende på vad du vill uppnå

Jag vill uppnå det bästa

Det är för 32-bit som jag ska köra. ARM processorer. Då kanske jag ska välja 9 decimaler....bara för att? Jag menar, det skadar väll inte om jag har 9 decimaler, trots att/om min processor har bara stöd för 7 decimaler?

Permalänk
Medlem
Skrivet av heretic16:

Jag vill uppnå det bästa

Det är för 32-bit som jag ska köra. ARM processorer. Då kanske jag ska välja 9 decimaler....bara för att? Jag menar, det skadar väll inte om jag har 9 decimaler, trots att/om min processor har bara stöd för 7 decimaler?

https://en.wikipedia.org/wiki/Single-precision_floating-point...

Om du vill "uppnå det bästa ;)" så skulle du kunna spara talen i dess flyttalsrepresentation i filerna om inte läsbarhet från filen är ett prio. Sen kan du konvertera talen till och från i programmet när du skriver till och från filen.

Visa signatur

Citera för svar

MSI Z490 MAG TOMAHAWK | Intel Core i7 10700K | Corsair 64GB DDR4 3200MHz | Asus GeForce RTX 3060 Ti TUF Gaming OC | Samsung 970 EVO Plus 1TB | WD Black 6TB Desktop Drive | Corsair RM750X 750W | Fractal Design Define R6

Permalänk
Medlem
Skrivet av heretic16:

Det jag ska göra är att jag har byggt en C-genererare som genererar en stor .h fil med massa statiska arrayer i.
Dessa värden har typ värderna 0.0002324 eller 0.000002342. Då tänkte jag om mer decimaler ökar precisionen eller inte.

Skrivet av heretic16:

Jag vill uppnå det bästa

Det är för 32-bit som jag ska köra. ARM processorer. Då kanske jag ska välja 9 decimaler....bara för att? Jag menar, det skadar väll inte om jag har 9 decimaler, trots att/om min processor har bara stöd för 7 decimaler?

Notera att du och @Yoshman talar om olika saker, decimaler är inte detsamma som signifikanta siffror. Dina två exempel har olika många decimaler, men samma antal signifikanta siffror (4 st, 2324).

Med det sagt, givet att du kör koden på ett system med likadan representation av flyttal som det som genererar koden kan du ju bara skriva ut talen i sin helhet. Bättre precision än så får du inte.

Permalänk
Medlem
Skrivet av SimpLar:

Notera att du och @Yoshman talar om olika saker, decimaler är inte detsamma som signifikanta siffror. Dina två exempel har olika många decimaler, men samma antal signifikanta siffror (4 st, 2324).

Det där är en mycket viktig skillnad.
"Hur många decimaler?" är i de flesta sammanhang fel fråga.
"Hur många signifikanta siffror?" är oftast en väldigt viktig sak att tänka på, i synnerhet om gör större beräkningar.

Har du en hyfsat modern C-kompilator så skriv ut flyttalen på hexadecimalt format. (använd %a konverteringen i fprintf och sscanf)
Då blir de normalt exakt representerade.

Permalänk
Skrivet av Erik_T:

Det där är en mycket viktig skillnad.
"Hur många decimaler?" är i de flesta sammanhang fel fråga.
"Hur många signifikanta siffror?" är oftast en väldigt viktig sak att tänka på, i synnerhet om gör större beräkningar.

Har du en hyfsat modern C-kompilator så skriv ut flyttalen på hexadecimalt format. (använd %a konverteringen i fprintf och sscanf)
Då blir de normalt exakt representerade.

När jag använde %af istället för %0.9ff så fick jag

0x1.96db980000000p-15f

Men detta är en funktion i C99. Jag använder mig av ANSI C (C89).

Serializering data i text är det jag vill uppnå.

Permalänk
Datavetare
Skrivet av heretic16:

Jag vill uppnå det bästa

Det är för 32-bit som jag ska köra. ARM processorer. Då kanske jag ska välja 9 decimaler....bara för att? Jag menar, det skadar väll inte om jag har 9 decimaler, trots att/om min processor har bara stöd för 7 decimaler?

Givet att du gör beräkningar lär du ändå aldrig kunna förutsätta fler än 6 signifikanta siffror då det kommer bli avrundning i mellanstegen.

Om det inte är mer än väl bör du köra 64-bit float, så 6 signifikativa siffror i konstanter blir rimligen fullt tillräckligt.

Arm (både 32-bit och ARM64, det är två olika ISA) och x86 representerar 32/64-bit flyttal på samma sätt (IEEE 754). Även grafikkort använder detta numera, var lite mer vilda västern för ett par årtionden sedan.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Skrivet av Yoshman:

Givet att du gör beräkningar lär du ändå aldrig kunna förutsätta fler än 6 signifikanta siffror då det kommer bli avrundning i mellanstegen.

Om det inte är mer än väl bör du köra 64-bit float, så 6 signifikativa siffror i konstanter blir rimligen fullt tillräckligt.

Arm (både 32-bit och ARM64, det är två olika ISA) och x86 representerar 32/64-bit flyttal på samma sätt (IEEE 754). Även grafikkort använder detta numera, var lite mer vilda västern för ett par årtionden sedan.

Så 6 decimaler är tillräckligt?
Det tycker jag också. Men ska man ta till 9 decimaler bara för att liksom?

Permalänk
Medlem
Skrivet av heretic16:

Så 6 decimaler är tillräckligt?
Det tycker jag också. Men ska man ta till 9 decimaler bara för att liksom?

Det är inte antalet decimaler som spelar roll, utan antal signifikanta siffror.
Som ett experiment, testkör följande lilla program, och fundera över hur relevant antalet decimaler är.

#include <stdio.h> int main(void) { float x = 0.000000123; printf("%.7f\n", x); printf("%.7e\n", x); }

Permalänk
Medlem
Skrivet av heretic16:

Det jag ska göra är att jag har byggt en C-genererare som genererar en stor .h fil med massa statiska arrayer i.
Dessa värden har typ värderna 0.0002324 eller 0.000002342. Då tänkte jag om mer decimaler ökar precisionen eller inte.

Nu beskrev du ju fortfarande inte problemet. Det är en ganska stor skillnad på om din data är temperatur ( då har du antagligen tillräckligt stor precision) eller om du ska spara värde av dina bitcoin i hela bitcoin (då kanske du vill ha ännu högre precision)
Återigen, beskriv ditt problem inte din lösning!

Permalänk
Skrivet av Erik_T:

Det är inte antalet decimaler som spelar roll, utan antal signifikanta siffror.
Som ett experiment, testkör följande lilla program, och fundera över hur relevant antalet decimaler är.

#include <stdio.h> int main(void) { float x = 0.000000123; printf("%.7f\n", x); printf("%.7e\n", x); }

Jag du har e som är en vetenskapligt uttryck. Den ena har mer siffror än andra. Alltså högre noggrannhet på %.7e.

Permalänk
Medlem
Skrivet av heretic16:

Så 6 decimaler är tillräckligt?
Det tycker jag också. Men ska man ta till 9 decimaler bara för att liksom?

Det går inte att lämna några absoluta garantier om det på förhand. Det beror helt på hur känsliga dina beräkningar är för avrundningsfel samt vilka krav du ställer på resultatet. Du måste helt enkelt prova vilken numerisk precision som generar tillräcklig noggrannhet för din tillämpning. Kan inte se att det skulle vara speciellt svårt att köra lite tester.

Avvägningen mellan single-, mixed- och double-precision pågår ständigt i forskarvärlden och även inom industrin. Alla vill såklart ha prestandan som kommer med att köra single precision men ifall noggrannheten kräver det så måste man helt enkelt gå upp. Det är tillämpningen som avgör.

Stavningsfel
Visa signatur

Asus P6X58D-E || Intel Core i7-930 || Corsair H50 || 3x4GB Crucial Ballistix Elite 1866MHz CL9 || Sapphire R9 390 Nitro 8GB || Sandisk Extreme II 2x120GB RAID 0 || Antec P183, 4 st Chassifläktar || Antec True Power 650W || ASUS VG248QE

Permalänk
Skrivet av Born_HardCORE:

Det går inte att lämna några absoluta garantier om det på förhand. Det beror helt på hur känsliga dina beräkningar är för avrundningsfel samt vilka krav du ställer på resultatet. Du måste helt enkelt prova vilken numerisk precision som generar tillräcklig noggrannhet för din tillämpning. Kan inte se att det skulle vara speciellt svårt att köra lite tester.

Avvägningen mellan single-, mixed- och double-precision pågår ständigt i forskarvärlden och även inom industrin. Alla vill såklart ha prestandan som kommer med att köra single precision men ifall noggrannheten kräver det så måste man helt enkelt gå upp. Det är tillämpningen som avgör.

Okej. Jag får testa om %0.9ef ger ett tillräckligt bra resultat.

Jag tror jag väljer 9 decimaler på grund utav float.h

#define FLT_DECIMAL_DIG 9 // # of decimal digits of rounding precision #define FLT_DIG 6 // # of decimal digits of precision #define FLT_EPSILON 1.192092896e-07F // smallest such that 1.0+FLT_EPSILON != 1.0

Permalänk
Medlem

Så du måste lagra flyttal i textformat som decimaltal, precitionen är väldigt viktig, men du får samtidigt inte använda 64-bitars tal? Det känns som något har gått riktigt fel i din kravspec, det är otroligt konstiga krav du har på dig, du måste nästan ha missförstått problemet du har lite.

Visa signatur

I just love the fact that there is a global integer variable named 'i'. Just think, you will never need to declare your loop variable again!
To avoid collisions where a loop that uses 'i' calls another function that loops with 'i', be sure to stack 'i' and restore it when your function exits.

Permalänk
Medlem
Skrivet av heretic16:

Så 6 decimaler är tillräckligt?
Det tycker jag också. Men ska man ta till 9 decimaler bara för att liksom?

du frågar efter enkel svar på något som kan vara väldigt komplext...

Det bero på vad du skall göra och det fins många fällor här som vid iterativa processer (som ränta på ränta och annuitetslån) där bristvärdiga antal värdesiffror kan göra att resultatet kan bli från flertal procent fel i slutändan till helt absurda värden - eller ännu värre i andra sammanhang i formelkedja som ger kaotisk beteende i iterativa dynamiska system (tänk fraktaler, mandebrot-figurer, fjärils-effekten där en fjärilsvingslag i Asien kan starta en tornado i USA några veckor senare då det var inom meteorologin man börja hitta dessa egenheter) där även en ändrad värde även 100 decimaler bort kan ge helt annan slutresultat.

också att tänka på om det är beräkningar som i sig har värden 1.0000023 som multipliceras upprepande någonstans i räkningskedjan.

Det fins anledning varför HP 12C är en standardräknare inom finansvärldens utbildningskurser då den tar hänsyn till sådant i sina beräkningsalgoritmer för tex. annuitetslån då de vidmakthåller antalet värdesiffror i sina beräkningar med olika trix - medans tar man formella formlerna för dessa operationer rakt av och stoppar in dessa som en programsnurra i en programmerbar miniräknare för tex. annuitetslån på många år så kan det bli många % fel i slutet just för att man tappar värdesiffror i beräkningssnurran och som de publika formlerna för operationerna inte tar hänsyn till och förutsätter att det är oändlig antal värdesiffror (eller hanterar som exakta kvoter) i beräkningarna. Att komma runt sådana saker kan vara rätt trixigt...

Du får kanske titta i någon lärobok om just numeriska beräkningar då mycket av hanteringen består av att förstå var felen kan uppträda och begränsa verkan av tex. avrundningsfel och helst gör att de tar ut varandra varannan gång i iterativa förlopp eller hantera värden väldigt nära 1 och att det inte ger exponentiell tillväxt av fel i någon riktning efter ett antal iterationer när man har värden med begränsad antal värdesiffror.

Dessutom ger räkning med basen 10 (BCD-räkning ala miniräknare och tidiga stordatorer) och beräkning baserat på basen 2 olika fel i olika scenarion - tex. kan inte 0.1 representeras exakt vid beräkning med basen 2 men kan hanteras exakt när det beräknas med basen 10 och motsvarande fall finns med exakta värden på basen 2 inte kan beskrivas exakt med basen 10 när man har begränsad antal värdesiffror, och värden av tex. 1/3 kan inte beskrivas exakt av någondera mer än att de uttrycks som en kvot - dvs. 1/3 i hela beräkningsskedjan utan att 'översättas' till någon annan talbas under beräkningen.

tex miniräknaren HP42S har decimal talbas i sina beräkningar - och dess motsvarighet för mobiler och laptop i form av free42 så kan man välja om den skall ha BCD (talbas 10) som beräkningsmaskin eller att det baseras standardlibbar i CPU som arbetar med basen 2.