Choosing Numeric Types for Computation
Access supplies the facts about a type. Checking compares those facts with what your task requires. A decision about a numeric type should come from the comparison, not from habit.
A Counter That Quietly Fails
Imagine a small program that keeps a running count of the items it processes. Each time an item arrives, the program adds one to the count. Most of the time nothing interesting happens, because the count stays small. But suppose the program runs for a long time, or it processes a very large batch. At some point the count may reach a value the chosen numeric type cannot hold. Nothing crashes at that moment. The program simply keeps going with a value that no longer matches reality, and the error may only show up later, far from its cause.
This is the central problem of this article. Every numeric type a program uses has properties of its own, and those properties determine what values the type can hold and how it behaves. A type that works well in one place may be unsuitable in another. Choosing a numeric type without looking at its properties is a guess, and that guess can go wrong quietly.
What do you think happens?
Before reading on, what would you need to know about a number type before trusting it with a value that could grow very large?
Reveal answer
You would need to know the range of values the type can hold, meaning its largest and smallest possible values, and whether its precision is enough for the job.
The source frames the whole topic around this question: the properties of a numeric type decide what it can hold and how it behaves, so those properties are what you check before relying on the type.
Adequacy Means Covering the Requirement
Adequacy is the property of a numeric type being suitable for a particular task: the type's properties cover the requirement of that task. A type is adequate when it can hold every value the task needs and provides the precision the task needs. A type is inadequate when some value the task requires falls outside what the type can represent.
Adequacy is a relationship between two things: a type and a requirement. The same type can be adequate for one program and inadequate for another. A type chosen for a small, bounded task is not automatically safe for a task whose values keep growing. This is why adequacy has to be judged against the specific job, not against a general feeling that a type is good.
Two Ideas: Access and Purpose
Two ideas connect everything in this article. The first is access. The properties of numeric types are accessible through numeric_limits, so you do not need to know them from memory or assume them. The second is purpose. You use numeric_limits to check that the numeric types you rely on are adequate for their use. Access gives you the information, and checking turns that information into a decision.
Access supplies the facts about a type. Checking compares those facts with what your task requires. A decision about a numeric type should come from the comparison, not from habit.
Looking Up Type Properties
When you query numeric_limits for a specific numeric type, you receive that type's properties. The properties named in this course's material include the minimum value, the maximum value, the number of digits the type can represent, and epsilon, which describes the gap between a value and the next representable value. Each type has its own entries, so the answer you get depends on which type you ask about.
The Ordered Checks for Adequacy
Checking adequacy is a sequence, not a single glance. Work through the steps in order. Start by stating what values the task requires, including the largest value it will realistically reach. Next, query numeric_limits for the candidate type and read its properties. Then compare the type's maximum and minimum against the required range. Then compare the precision the type offers against the precision the task needs. If either comparison fails, choose a different type and run the checks again. If both pass, the type is adequate for this task. Because requirements change over time, return to the first step whenever they do.
Tracing a Value Past Its Maximum
Return to the running count. Suppose the count is stored in a type whose maximum is reached during processing. The value stored just before the overflow is still a correct reading of the count. The arithmetic result that goes past the maximum is no longer something the type can represent, so the variable no longer holds a correct count. The diagram below traces that change. The important point is that the variable gives no obvious warning at the moment it changes.
Mistakes Developers Make With Numeric Types
Common mistake Trusting a type because it worked in a previous program
What it looks likeA type that handled a small batch is reused for a much larger one without any check.
Why it failsAdequacy is judged against a specific task. A type that suited one set of requirements may not cover a new set.
Do this insteadRun the adequacy checks again whenever the program or its requirements change.
Common mistake Choosing a type from memory
What it looks likeA programmer assumes a type's maximum value without looking it up.
Why it failsThe properties of numeric types are accessible through
numeric_limits, so relying on memory replaces a reliable source with a guess.Do this insteadQuery numeric_limits for the candidate type and use the values it reports.
Common mistake Checking the range but ignoring precision
What it looks likeA type's maximum is large enough, but the task needs fine fractional detail the type cannot represent.
Why it failsAdequacy means the type's properties cover the requirement, and precision is one of those properties.
Do this insteadCompare both range and precision against the task before deciding.
Common mistake Believing an out-of-range result will always announce itself
Applying the Checks to a New Task
A program records how many sensor readings it has received since it started. The readings arrive continuously and the program is expected to run for a long time. Describe the adequacy checks you would perform before choosing a numeric type for this count. Name the question you would ask at each step and what result would send you back to choose a different type.
Hints
- Start by stating the largest value the count could realistically reach, given how long the program runs.
- Which property of
numeric_limitsanswers whether that largest value fits? - What would you do if the candidate type's maximum is smaller than your required largest value?
Key Takeaways
- The properties of numeric types are accessible through
numeric_limits, so you can check them instead of relying on memory or assumption. - Adequacy means a numeric type's properties cover the requirement of the specific task, including its range and precision.
- Checking adequacy is an ordered sequence: state the requirement, query the candidate type, compare range and precision, then choose or reject the type.
- A value that exceeds a type's range can silently become incorrect, so the check must happen before the type is trusted.
- Recheck numeric type properties whenever the task's requirements change.