data transformation
value mapping
range conversion
scaling values
data normalization

Mapping a range of values to another

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Mapping one numeric range to another is a standard linear transformation problem. If a value x lies in a source interval from a to b, and you want the corresponding value in a destination interval from c to d, the usual formula is y = c + (x - a) * (d - c) / (b - a).

This formula preserves relative position. A midpoint in the source range becomes a midpoint in the target range, endpoints map to endpoints, and values outside the source range extrapolate unless you explicitly clamp them.

The Basic Formula

A direct implementation is simple:

python
1def map_range(x, a, b, c, d):
2    return c + (x - a) * (d - c) / (b - a)
3
4print(map_range(5, 0, 10, 0, 100))

This prints 50.0, which is exactly what you expect because 5 is halfway between 0 and 10.

Why the Formula Works

The mapping happens in two stages:

  1. normalize the source value into a fraction of the source interval
  2. scale that fraction into the destination interval

The normalized position is:

(x - a) / (b - a)

Once you have that ratio, multiply it by the destination range width and add the destination start.

That is why the mapping is linear and position-preserving.

A Safer Implementation

The edge case you must handle is a zero-width source interval. If a == b, the formula divides by zero.

python
1def map_range(x, a, b, c, d):
2    if a == b:
3        raise ValueError("source range cannot have zero width")
4    return c + (x - a) * (d - c) / (b - a)

That is usually the right default because a collapsed source interval does not define a meaningful scale.

Clamping Versus Extrapolation

The basic formula extrapolates outside the destination range when the source value lies outside the source interval.

python
print(map_range(15, 0, 10, 0, 100))

This prints 150.0, not 100.0.

That is not a bug. It is ordinary linear extrapolation.

If your application wants clamping instead, add it deliberately:

python
1def map_range_clamped(x, a, b, c, d):
2    if a == b:
3        raise ValueError("source range cannot have zero width")
4
5    low = min(a, b)
6    high = max(a, b)
7    x = max(low, min(high, x))
8
9    return c + (x - a) * (d - c) / (b - a)

Use clamping only when the domain logic calls for it, such as UI sliders or bounded sensor displays.

Reversed Ranges Also Work

The source or destination interval can run in reverse.

python
print(map_range(25, 0, 100, 1, 0))

This maps 25 percent of the way through the source interval to 0.75 in the inverted target interval.

That makes the same formula useful for:

  • inverting progress bars
  • translating between coordinate systems
  • mapping screen coordinates to mathematical axes

Integer Results Versus Floating Results

The formula naturally returns a floating-point result. That is usually what you want during the calculation.

If the final domain is discrete, round at the end.

python
1def map_range_int(x, a, b, c, d):
2    return round(map_range(x, a, b, c, d))
3
4print(map_range_int(3, 0, 10, 0, 255))

Keeping the internal result as a float until the final step avoids losing precision too early.

Common Uses

Range mapping shows up everywhere:

  • converting joystick input to motor output
  • mapping percentages into physical units
  • normalizing data for visualization
  • translating one coordinate system into another
  • scaling sensor readings into display ranges

Once you recognize it as linear interpolation or linear scaling, the implementation becomes straightforward.

Common Pitfalls

The biggest mistake is forgetting the zero-width case where a == b. Another is expecting clamping when the formula is actually extrapolating outside the target interval. Developers also sometimes use integer arithmetic too early in languages where division truncates, which destroys accuracy. Finally, if either range is reversed, make sure that reversal is intentional rather than an unnoticed bug in the input data.

Summary

  • The standard linear mapping formula is y = c + (x - a) * (d - c) / (b - a).
  • It preserves relative position from one interval to another.
  • Handle a == b explicitly to avoid division by zero.
  • Decide whether your application wants extrapolation or clamping.
  • The same formula works for normal and reversed intervals.

Course illustration
Course illustration

All Rights Reserved.