Avrundning och manipulatorer Intern avrundning Avrundning vid utskrift o o Med formatflaggor Med manipuilatorer Andra manipulatorer o Exempel 1
Intern avrundning Intern avrundning används t ex då en variabel behöver avrundas innan den användes vidare "Avrunda först inkomsten nedåt till närmaste 100-tal, beräkna sedan skatten" då man behöver avrunda till hela 10-tal, 100-tal, då man avrundar på speciellt sätt "Avrunda till närmaste 50-öring" Princip: I C++ : Avrunda 1.456 till n decimaler Flytta decimaltecknet n steg åt höger: 145.6 Avrunda till närmaste heltal: 146.6 Flytta tillbaka decimaltecknet n steg: 1.46 double tal = 1.456; n=2 här floor(x) ger det största heltal som är x x x -2-1 0 1 2 tal = floor(tal*100+0.5)/100; // Avrunda tal till 2 decimaler Flytta kommat två steg åt höger Avrunda till närmaste lägre heltal Flytta tillbaka kommat två steg åt vänster 2
Intern avrundning - exempel // Avrundning till 100-del (2 decimaler) double tal = floor(tal*100 + 0.5) / 100; // Avrundning till 10-del (1 decimal) double tal = floor(tal*10 + 0.5) / 10; // Avrundning till 2-del (50-öring) double kr = floor(kr*2 + 0.5) / 2; OBS viktigt med 10.0 om tal är ett heltal // Avrundning till heltal int heltal = floor(tal + 0.5); // Avrundning till 10-tal double tal = floor(tal/10.0 + 0.5)*10; Man ser ofta intern avrundning utföras med typning till int istället för floor()! OBS! Detta gäller endast för positiva tal! double tal = int(tal * 100 + 0.5) / 100.0; // Viktigt att dela med 100.0 för // att få decimaler 3
Avrundning vid utskrift - setf() Använd i första hand "avrundning vid utskrift" - till cout finns ett antal flaggor som bl a styr precision och decimaler - flaggorna kan påverkas direkt eller med manipulatorer. Avrundning till 2 decimaler med setf() (sätter värden på I/O-flaggorna) cout.setf(ios_base::fixed); cout.setf(ios_base::showpoint); cout.precision(2); // Vanliga decimaltal // Visa decimaler även om de är noll // Sätt två decimaler double pris = 125.5678; cout << pris << "kr" // Skriver ut pris med 2 decimaler, dvs 125.57kr Precisionen gäller tills den ändras Utelämnas cout.setf(ios_base::fixed)ger cout.precision(2) två värdesiffror i stället för 2 decimaler I tidigare versioner av C++ användes ios:: i stället för ios_base:: 4
Avrundning vid utskrift - Manipulatorer Stream a b c MANIPULATOR A B C Stream En stream är en följd av byte En manipulator kan infogas i en ström och påverkar denna på något sätt. Avrundning till 2 decimaler med manipulatorer #include <iomanip>... cout << fixed << showpoint << setprecision(2); //Sätter flaggor med manipulatorer double pris = 125.0; cout << pris << "kr" // Skriver ut pris med 2 decimaler, dvs 125.00kr Setprecision(2) gäller tills den ändras Utelämnas fixed ger setprecision(2) två värdesiffror i stället för 2 decimaler Ett alternativ till fixed är scientific som ger utskrift i 10-potensformat. T ex 125.5678 blir 0.13E02 med cout << scientific << setprecision(2); 5
Andra manipulatorer Som alternativ till flaggorna som används till att formatera in- och utströmmarna finns det manipulatorer - Här visas de vanligaste: Manipulator Egenskap endl Radframmatning och tömmer buffert ends Avslutar sträng flush Tömmer buffert dec / hex / oct In- och utmatning i dec/hex/oct setfill(char) Sätter utfyllnadstecken setprecision(int) Sätter decimaler för flyttal i fixed format setw(int) Sätter fältvidd fixed/scientific Sätter fasttalsformat/10-potensformat left / right Vänster / höger-justerad utskrift showpos / noshowpos Visa inledande + showbase/noshowbase Visa 0xnnnn el 0nnnn boolalpha / noboolalpha Visa true/false Alla manipulatorer utom setw() sätter det nya värdet permanent 6
#include <iostream.h> #include <iomanip.h> int main() { int tal; Manipulatorer - Exempel setfill är bra om du ska skriva ut ett datum, t ex 2005-04-02 (Använd setfill( 0 ) och setw(2)) cout << endl << "Ange ett hex-tal : "; cin >> hex >> tal; // Hexadecimal inmatning cout << setfill('0'); // Fyll ut med 0 cout << " Hex :" << hex << setw(3) << tal // Skriv högerjust. i kolumnvidd 3 << " Dec :" << dec << setw(4) << tal // - - - - 4 << " Okt :" << oct << setw(5) << tal // - - - - 5 << endl << endl; cout << setfill(' '); // Återställ till (standard-)utfyllnad return 0; } Körexempel Ange ett hex-tal : 20 Hex :020 Dec :0032 Okt :00040 setw() gäller bara en utskrift. Övriga formateringsmanipulatorer gäller tills de ändras. 7
Ex 1 Utskrift i kolumner med 2 och 4 decimaler på samma rad const double PI=4*atan(1); // Värdet på pi, dvs 3.14159 cout << fixed << showpoint << setfill('#') << setprecision(3) << setw(10) << PI << setprecision(4) << setw(8) << sqrt(2) << setfill(' ') << endl; Ex 2 Utskrift: Utskrift med decimaler i kolumner / tabeller #####3.142##1.4142 10 8 Utfyllt med # för att visa kolumner - normalt används blanktecken Utskrift med utfylld blandad justering (vä/hö) för tabeller cout << fixed << showpoint << setfill('#'); cout << right << setw(9) << setprecision(2) << tal1 << ' << left << setw(9) << namn << ' << right << setw(9) << setprecision(4) << tal2; cout <<setfill(' '); Koden körd tre gånger med olika värden på variablerna ###416.23 Svensson# #232.4500 #####6.50 Ekman#### ###3.4500 #12345.67 Testman## ##17.5670 Strängar vänsterjusteras Numeriska värden högerjusteras 8