C++ Data Types: int, double and Type Conversion
Choose C++ int, double, bool and char deliberately. Fix integer division, inspect numeric limits, understand narrowing and floating-point approximation, and calculate a meaningful average.
What you will learn
- Match a type to the kind of value it represents.
- Predict integer division before a result is assigned.
- Convert an operand deliberately rather than casting a truncated result.
- Explain range, narrowing and floating-point approximation.
- Separate storage, calculation and display precision.
Choose the meaning before choosing the type
A type tells C++ how a value can be represented and which operations make sense. It does not supply the complete meaning of your data. A count of books and a temperature can both be numbers, but one usually needs whole units and the other may need a fractional part. Write the unit and permitted range beside the requirement before choosing a declaration. This prevents a technically valid calculation from answering the wrong question.
Use int for modest whole-number examples that may involve negative values. Use double for approximate real-number measurements and ratios. bool represents true or false, such as whether a reading passed validation. char represents one character code unit, not arbitrary human text. std::string is a library type for a sequence of characters. Quoting a digit as '7' creates a character; writing 7 creates an integer literal. Those values are not interchangeable descriptions of the same object.
The spelling of the initializer matters. In these examples 7 is an int literal and 7.0 is a double literal. A suffix can select another type, but adding suffixes without understanding them only hides the conversion path. Keep beginner examples explicit and small. For user-facing text, use a string rather than hoping a single char can represent a complete accented symbol or emoji. Text encoding deserves its own treatment beyond this numeric lesson.
Why double result = 7 / 2 still stores 3
Both operands in 7 / 2 are integers, so this operation uses integer division. Its result is 3: the fractional part is discarded. Assigning that result to double later converts 3 into a floating-point value; it cannot recover the lost half. Read the expression from its operands toward its destination. The declaration on the left does not instruct every operation on the right to become floating-point arithmetic.
Convert an operand before the division when the required answer is a ratio. static_cast<double>(total) / count makes the conversion visible. With the small values here, converting total is exact, and the mixed operation converts count to double as well. Casting total / count instead is too late. Replacing a cast with a floating-point literal is suitable when the denominator really is a fixed literal, but named counts should keep their meaning and not become unexplained constants.
Integer division truncates toward zero, not toward negative infinity. For example, -7 / 2 produces -3. The remainder operator belongs to integer arithmetic; -7 % 2 is -1 for this case. Avoid treating remainder as a universal mathematical modulo operation for negative values. Also never divide or take remainder by zero. Keep the denominator nonzero by design, or check it before computing; the conditions lesson explains the branch that protects the operation.
Compare a late conversion with an early conversion
Predict both averages. fixed and setprecision format the printed double values; they do not repair the first calculation.
Predict the output, edit the source, then select Run code.
Compare with the starter's expected output
Late: 3.00
Early: 3.50
After editing inputs, calculate a new prediction; this reference describes only the starter.
Range and signedness are part of the contract
Do not assume int always occupies exactly four bytes or that every platform has identical numeric limits. The standard guarantees minimum capabilities; your implementation provides actual limits. Include limits and inspect std::numeric_limits<int>::lowest() and max() for your chosen target. Those observations describe that build environment, not an eternal property of all C++ systems. sizeof reports storage in C++ bytes, whose definition is not a promise that every byte has eight bits.
Unsigned types represent nonnegative values and use modular arithmetic for their range. That does not make them a general-purpose solution to invalid negative input. A negative value converted to an unsigned type can become a large positive value. Mixing signed and unsigned operands can also change a comparison's meaning through conversions. For these small instructional counts, retain int and validate the domain rather than adding unsigned as a decoration.
Signed integer overflow is not a reliable wrapping calculation. Do not run an overflowing expression and use the observed result as a rule. A larger type can help only if its range is actually sufficient for every intermediate expression. A final destination with extra range does not rescue an earlier overflowing multiplication. Later validation and testing lessons develop checked calculations; here constrain inputs and explain the bounds you rely on.
Braces reveal some unwanted conversions
Brace initialization rejects certain narrowing conversions. int sessions{2.5} therefore fails in C++20 instead of silently discarding a fraction. This is a valuable diagnostic, not an obstacle to remove automatically. Ask whether sessions is truly a whole count, whether the initializer is wrong, or whether the model needs a fractional type. Different answers require different repairs. A cast documents an explicit conversion but does not prove the conversion is appropriate or safe.
Converting a floating-point value to an integer discards the fractional part toward zero when the result is representable. It is not ordinary rounding. A conversion outside the destination's representable range is unsafe. Do not use a cast as an input-validation strategy. Check the requirement and range before converting, and keep the original value if the report still needs its fraction. This distinction becomes especially important when parsing measurements supplied by a user.
Repair a narrowing declaration
Intentional compile failure. Choose int sessions{2} for two complete sessions, or double sessions{2.5} if fractional sessions are part of the requirement. Explain the model before selecting the repair.
Predict the output, edit the source, then select Run code.
Display precision is not numerical exactness
Floating-point types have finite precision. On common binary implementations, many decimal fractions are approximations. A short printed value can hide that approximation because stream formatting rounds the display. Printing two decimal places does not change the stored object or establish that two computed values are exactly equal. Avoid a universal tolerance constant: a useful comparison depends on the scale, acceptable error and kind of measurement being modeled.
Money needs a deliberately specified representation and rounding policy. For a small whole-cent example, storing 1250 cents as an integer avoids introducing an approximate decimal dollar value. That is not a complete accounting solution: currency, overflow, fractional cents, tax rules and rounding still need explicit decisions. Use double for our average lesson because a ratio is intended; do not generalize that choice to every financial quantity simply because its output contains a decimal point.
To review a numeric expression, write four answers: the type of each operand, the operation performed, the range of the intermediate result, and the final display format. This separates a storage mistake from a formula mistake and a presentation mistake. Change total from seven to eight and then to zero while leaving count at two. Predict each result first. An empty data set is a separate state, not an invitation to divide by a zero count.
Build and run the local examples
Save one complete example or lab solution as main.cpp. Choose your installed toolchain; run only after a successful build. Input examples wait for text in your terminal. The browser teaching interpreter does not support these full-language features.
macOS / Clang:
clang++ -std=c++20 -Wall -Wextra -Wpedantic main.cpp -o lesson
./lesson
Linux / GCC:
g++ -std=c++20 -Wall -Wextra -Wpedantic main.cpp -o lesson
./lesson
Windows Developer Command Prompt / MSVC:
cl /std:c++20 /EHsc /W4 main.cpp /Fe:lesson.exe
lesson.exeIndependent lab
Report the average pages read across four sessions without losing the fractional part. Explain why the count cannot be zero.
Acceptance checklist
- Initialize totalPages to 11 and sessionCount to 4 as int values.
- Compute a double average by converting before division.
- Print Average pages: 2.75 with exactly two decimal places.
- Change totalPages to 12 and predict 3.00.
- Explain why an empty session set needs a separate decision, not division by zero.
Need a hint?
- Cast an operand, not the already computed quotient.
- Include iomanip for fixed and setprecision.
- Keep the unit pages per session in your explanation.
Write and run your lab
Build your own solution before revealing the reference. Use the input field for normal, boundary and invalid cases; this runner executes your program but does not grade it.
Predict the output, edit the source, then select Run code.
Your lab evidence and notes
Record predictions, actual output, commands and the cause of each repair. Code is plain text: this scratchpad does not execute or grade C++.
Loading local notes…
Review your acceptance checklist and quiz explanations before marking this lesson complete. This is self-review, not a grade or certification.
Reveal the explained lab solution
Reference lab solution
Compare the reference with your own reasoning. Running this solution does not grade or complete the lesson.
Predict the output, edit the source, then select Run code.
Expected output
Average pages: 2.75
The total and count remain whole-number facts; only the ratio needs a fractional representation.
Converting totalPages before division preserves the intended fraction. Converting 11 / 4 afterward would store 2 instead.
The lab fixes sessionCount at four. A generalized program must reject or separately report zero sessions before computing an average.
Review before moving on
Explain the lesson's objectives in your own words, compare your lab evidence with the acceptance checklist, and keep the first failing case alongside your repair. Completing a page is not proof that every C++ feature or input is supported.
- Match a type to the kind of value it represents.
- Predict integer division before a result is assigned.
- Convert an operand deliberately rather than casting a truncated result.
- Explain range, narrowing and floating-point approximation.
- Separate storage, calculation and display precision.
References and further reading
Original examples and exercises accompany these primary references. Tool-specific diagnostics and support depend on your installed version.