cadence_learn
the_c++_track / level 06 of 15 ▶ 15 min

your money prints as 5.

A total of five pounds shows as “5”, and setprecision(2) can put scientific notation in a receipt. Three lines fix it — and one distinction explains every crooked table you will ever write.

after this level you'll be able to
  • Print a number to exactly two decimal places, every time
  • Say why setprecision(2) alone can produce scientific notation
  • Line up a table, and know which settings you must repeat
the problem

your money prints as 5

You have worked out a total. It is five pounds exactly. You print it, and C++ shows you this:

output
Total: 5
# not 5.00 — and an assignment asking for currency will be marked down for it

Two things are happening, and neither is obvious. A double holding 5.0 prints as 5, because trailing zeros are not significant. And C++ shows about six significant digits by default — so 1234.5678 comes out as 1234.57 without you asking for anything at all.

the whole fix, three lines

Add the include at the top, then set it once before you print:

#include <iomanip> cout << fixed << setprecision(2); cout << "Total: " << total << endl; // Total: 5.00
◈ ask an ai about this

“How do I print a number to exactly two decimal places in C++, like money?”

chatgpt ↗ claude ↗

the trap

setprecision on its own does not mean decimal places

This is the one that costs an evening. Used alone, setprecision(2) means two significant figures — not two decimal places. Verified on a real compiler:

output
cout << setprecision(2) << 1234.5678;
1.2e+03   # scientific notation. two significant figures.

cout << fixed << setprecision(2) << 1234.5678;
1234.57  # two DECIMAL places. what you meant.

fixed is the word that changes the meaning from “significant figures” to “places after the point”. Leave it out and you can get scientific notation in a receipt, which looks like the program is badly broken when it is doing exactly what you said.

set once versus set every time
STICKY — fixed, setprecision, setfill, left/right setprecision(2) 19.50 7.25 5.00 …and everything after that, forever SET ONCE — STAYS ON ONE-SHOT — setw setw(10)        Ada Grace Alan FORGOTTEN ALREADY not padded — the width was used up This one distinction explains nearly every “why is my table crooked?” question. setw must be repeated before EVERY column.
Set the decimals once; set the width every single time. Nothing announces this, and a table where only the first column lines up is the result.
try it yourself

switch each piece on and watch the output

▤ lab 06 · the formatting bench

Every line below is what the real compiler prints. Try setprecision without fixed.

output

        
Pick a value, then switch on fixed and setprecision together.
◈ ask an ai about this

“What is the difference between setprecision and fixed in C++, and why does setw only work once?”

chatgpt ↗ claude ↗

the other half

lining a table up

Once numbers look right, the next assignment asks for a table. Three tools, and they behave differently from each other in a way nobody warns you about.

cout << setw(12) << left << name << setw(8) << right << score << endl;

setw(n) sets a minimum width. left and right decide which side the padding goes. setfill('.') changes the padding character from a space.

the difference that makes tables crooked

setw applies to the very next thing printed, and then forgets. Everything else — fixed, setprecision, left, setfill — stays switched on until you change it.

So you set the decimals once, and you repeat setw before every single column. Verified — with one setw(10) at the front, only the first name is padded and the rest run together.

one last surprise

2.675 rounds to 2.67

Ask C++ to show 2.675 to two decimal places and you get 2.67, not 2.68. That is not a rounding rule you have forgotten — it is level 8 arriving again.

The number stored is not exactly 2.675. It is a hair below it, because a two-state machine cannot write that value exactly, so rounding to two places honestly gives 2.67. Nothing here is broken and there is no flag that fixes it — which is one more reason to keep money in whole pennies as an int, and only divide by 100 at the very moment you print.

what to actually do about it

For coursework, fixed and setprecision(2) are what your professor is asking for and are entirely fine. Just do not be surprised by a half-penny, and do not spend an hour hunting a bug that is really the machine telling the truth.

do this together

make a receipt line up

☶ two people · 12 minutes

One writes the format. One is the awkward customer with the awkward numbers.

person a

Write the cout line for a receipt row: item name on the left, price on the right, aligned in a column.

person b

Hand over the values that break it. A very long item name. A price of exactly 5. A price of 1234.5. Zero. A negative.

The interesting failure is the long name: setw is a MINIMUM, not a maximum, so a name wider than the column pushes everything after it out of line and nothing complains. That is a boundary case in the level-11 sense, and it is the reason real receipts truncate long names.

what to keep

three things worth remembering

01

fixed, then setprecision

Without fixed you get significant figures — and scientific notation in your receipt.

02

Width every time, decimals once

setw is one-shot. Everything else stays on until changed. This is why tables go crooked.

03

setw is a minimum

Something wider than the column pushes the rest out of line, silently.

check yourself

4 questions before you move on

Not recall — these are the shapes an exam actually uses. Every answer below was produced by compiling and running the code, so if you disagree with one, the compiler is the one to believe.

▢ check yourself4 questions

Have a real go before revealing. Being wrong here is worth more than being right in three weeks.

01

A total of exactly five pounds. What does this print?

double p = 5.0; cout << p;
02

This is the trap. What comes out?

cout << setprecision(2) << 1234.5678;
03

Now with the fix.

cout << fixed << setprecision(2) << 5.0;
04

Both names are inside one setw(6). What does the line look like? (Use spaces exactly.)

cout << "|" << setw(6) << "Ada" << "|" << "Bo" << "|";
answered: 0 of 4right first time: 0
Stuck? Peter reads these personally and replies to your email.
Ask Peter →