Gå til innhold

If og else, er jeg helt på jordet?


Anbefalte innlegg

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
Videoannonse
Annonse

"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 av lnostdal
Lenke til kommentar

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
  • 2 uker senere...

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...