buskmann Skrevet 30. august 2006 Del Skrevet 30. august 2006 Jeg har en timeout-funksjon som kjører slår til med faste intervaller: void timeout_funksjon (void) { static float prosent = 0; prosent += 0.1; if (prosent > 1.0) { printf("Prosent var %f, nå 0\n", prosent); prosent = 0; } else { printf("Prosent er %f\n", prosent); } } Dette gir denne utrskiften: Prosent er 0.100000 Prosent er 0.200000 Prosent er 0.300000 Prosent er 0.400000 Prosent er 0.500000 Prosent er 0.600000 Prosent er 0.700000 Prosent er 0.800000 Prosent er 0.900000 Prosent var 1.000000, nå 0 Prosent er 0.100000 Prosent er 0.200000 Prosent er 0.300000 Prosent er 0.400000 Prosent er 0.500000 Prosent er 0.600000 Prosent er 0.700000 Prosent er 0.800000 Prosent er 0.900000 Prosent var 1.000000, nå 0 Prosent er 0.100000 Er ikke dette høl i hue? If-testen skal vel ikke slå til før prosent er 1.1? Kompileres med GCC 4.1. Lenke til kommentar
lnostdal Skrevet 30. august 2006 Del Skrevet 30. august 2006 (endret) "What every computer scientist should know about floating-point arithmetic." ==> google edit: Tipper du kan få printf til å skrive ut flere desimaler, da ser du hva som skjer. Dette skjer på samme vis uansett språk: cl-user> (let ((i 0)) (loop (incf i 0.1) (format t "i = ~A~%" i) (when (> i 1.0) (write-line "reset!") (setf i 0)) (sleep 1))) i = 0.1 i = 0.2 i = 0.3 i = 0.4 i = 0.5 i = 0.6 i = 0.70000005 i = 0.8000001 i = 0.9000001 i = 1.0000001 reset! i = 0.1 i = 0.2 i = 0.3 i = 0.4 i = 0.5 i = 0.6 i = 0.70000005 i = 0.8000001 i = 0.9000001 i = 1.0000001 reset! ..også når jeg bruker double (den defaulter til C's float over): cl-user> (let ((i 0d0)) (loop (incf i 0.1d0) (format t "i = ~A~%" i) (when (> i 1.0d0) (write-line "reset!") (setf i 0d0)) (sleep 1))) i = 0.1d0 i = 0.2d0 i = 0.30000000000000004d0 i = 0.4d0 i = 0.5d0 i = 0.6d0 i = 0.7d0 i = 0.7999999999999999d0 i = 0.8999999999999999d0 i = 0.9999999999999999d0 i = 1.0999999999999999d0 reset! i = 0.1d0 i = 0.2d0 Som et alternativ kan du gå over til "brøk" (C.L. har innebygget støtte for dette btw.) i stedet for flytetall. Da lagrer du to heltall - teller og nevner, og oppnår dermed 100% nøyaktighet. Du kan også lagre det forran komma som et tall og det etter komma som et tall på et lignende vis - om jeg ikke husker helt feil i farta her. Endret 30. august 2006 av lnostdal Lenke til kommentar
buskmann Skrevet 30. august 2006 Forfatter Del Skrevet 30. august 2006 OK, da gjør jeg det. Lenke til kommentar
knatten Skrevet 31. august 2006 Del Skrevet 31. august 2006 Et annet triks er å bruke en integer til å telle prosent med, så slipper du avrundingsfeil. prosent = 1 if (prosent > 10) Men da blir vel variabelnavnet litt missvisende. Uansett, bruk integers når du kan for å unngå akkumulerende avrundingsfeil. Lenke til kommentar
buskmann Skrevet 31. august 2006 Forfatter Del Skrevet 31. august 2006 (endret) Ja, det var det jeg endte opp med, og det jeg tror lnostdal mente også. int prosent = 0; prosent++; if (prosent > 1000) prosent = 0; // argument er prosent settverdi((float)prosent/(float)1000); Endret 31. august 2006 av buskmann Lenke til kommentar
Svish Skrevet 11. september 2006 Del Skrevet 11. september 2006 her har du litt interessant lesning vett: http://en.wikipedia.org/wiki/Floating_point er i blant kjekt å vite litt sånne ting når en programmerer Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå