C-programmering: lussen en drijvende-kommaprecisie in conversietabellen repareren

3

Het schrijven van een eenvoudige temperatuuromzetter klinkt triviaal totdat je beseft hoe gemakkelijk fundamentele logica breekt. Je begint met een ‘while’-lus, je draait een tabel van Fahrenheit naar Celsius en alles lijkt in orde. Maar dan heb je een specifiek datapunt nodig, zoals de menselijke lichaamstemperatuur, en plotseling verandert je schone code in een foutopsporingsnachtmerrie.

Hier ziet u in de praktijk hoe looping werkt in C, waarom precisie belangrijk is en hoe u kunt voorkomen dat uw programma’s voor altijd blijven hangen.

De basis: gehele lussen

Laten we eens kijken naar de eenvoudigst mogelijke versie. U wilt een tabel afdrukken van 0 tot 100 graden Fahrenheit, met een sprong van 10 seconden. Je gebruikt een geheel getal int voor de teller a.

Voer dit uit en je krijgt een schoon raster:

Het is functioneel. Het is snel. Maar het is lelijk. Waarom? Omdat het delen van gehele getallen decimalen afkapt. (a - 32) * 5 / 9 laat het fractionele deel vallen voordat het wordt afgedrukt. Als je nauwkeurigheid nodig hebt, heb je getallen met drijvende komma nodig.

Drijvende-kommaprecisie

Als u overschakelt naar ‘float’, verandert de wiskunde. U moet ook de formaatspecificatie wijzigen van %d naar %f. De onderstaande code gebruikt %6.2f, wat de printer vertelt zes spaties te reserveren, met twee cijfers achter de komma.

Nu heeft de uitvoer daadwerkelijke decimalen. Het ziet er professioneel uit. Maar wat als u een specifieke waarde nodig heeft die niet in het patroon past?

De lichaamstemperatuurbug

Stel je voor dat je 98,6°F (normale menselijke lichaamstemperatuur) in die tabel wilt invoeren. Het komt niet op een veelvoud van 10 terecht. Je voegt dus een ‘if’-statement toe.

Het werkt voor 100. Maar verander de luslimiet naar 200, en de logica stort in. De voorwaarde if (a > 98.6) blijft waar voor elke volgende iteratie. Je print keer op keer bij 98,6°F.

Waarom gebeurt dit? Omdat de voorwaarde controleert of het huidige getal groter is dan 98,6. Zodra a 100 bereikt, zal deze altijd groter zijn dan 98,6. Je controleert niet of je het net hebt gehaald. Je controleert of je er voorbij bent.

De oplossing: trackingstatus

Om dit op te lossen, moet u de vorige waarde onthouden. Je introduceert een tweede variabele, b, geïnitialiseerd op -1.

Nu klopt de logica. Het drukt alleen de extra regel af als a momenteel boven 98,6 is EN b eerder onder 98 was

Vorig artikelWaarom de technologische singulariteit daadwerkelijk zou kunnen plaatsvinden in 2030
Volgend artikelHoe u de veiligste telefoon kiest: hardware, software en ondersteuning balanceren