etl/docs/maths/scaled-rounding.md
2026-04-16 12:40:36 +02:00

342 lines
5.0 KiB
Markdown

---
title: "Scaled Rounding"
---
Rounding algorithms for scaled integral values.
From `20.40.1` all scaling functions are `ETL_NODISCARD` and `ETL_CONSTEXPR14`.
It is often advantageous to use scaled integral values rather than floating point for performance reasons.
These functions will round the supplied values according to various popular rounding algorithms.
See [http://www.clivemaxfield.com/diycalculator/sp-round.shtml](http://www.clivemaxfield.com/diycalculator/sp-round.shtml)
The results may be scaled or unscaled.
**Scaled**
The result has the same scaling as the input value.
**Unscaled**
The result has the scaling factor removed from the input value. 'Unscaled' is a little faster than 'scaled'.
Assume a scaling factor of `10` for all of the examples below (simulated one decimal place).
i.e. `5.1` => `51`
## Round Ceiling
Values are rounded to the next more positive integral value.
```cpp
template <size_t Scaling, typename T>
T round_ceiling_scaled(T value)
```
**Description** |
```cpp
-54 => -50 -5.4 => -5.0
-55 => -50 -5.5 => -5.0
-56 => -50 -5.6 => -5.0
54 => 60 5.4 => 6.0
55 => 60 5.5 => 6.0
56 => 60 5.5 => 6.0
```
---
```cpp
template <size_t Scaling, typename T>
T round_ceiling_unscaled(T value)
```
**Description** |
```cpp
-54 => -5 -5.4 => -5
-55 => -5 -5.5 => -5
-56 => -5 -5.6 => -5
54 => 6 5.4 => 6
55 => 6 5.5 => 6
56 => 6 5.6 => 6
```
## Round Floor
Values are rounded to the next more negative integral value.
```cpp
template <size_t Scaling, typename T>
T round_floor_scaled(T value)
```
**Description** |
```cpp
-54 => -60 -5.4 => -6.0
-55 => -60 -5.5 => -6.0
-56 => -60 -5.6 => -6.0
54 => 50 5.4 => 5.0
55 => 50 5.5 => 5.0
56 => 50 5.6 => 5.0
```
---
```cpp
template <size_t Scaling, typename T>
T round_floor_unscaled(T value)
```
**Description** |
```cpp
-54 => -6 -5.4 => -6
-55 => -6 -5.5 => -6
-56 => -6 -5.6 => -6
54 => 5 5.4 => 5
55 => 5 5.5 => 5
56 => 5 5.6 => 5
```
## Round Half Up
Values are rounded to the nearest integral value.
'Half' values are rounded up (towards infinity).
```cpp
template <size_t Scaling, typename T>
T round_half_up_scaled(T value)
```
**Description** |
```cpp
-54 => -50 -5.4 => -5.0
-55 => -60 -5.5 => -5.0
-56 => -60 -5.6 => -5.0
54 => 50
55 => 60
56 => 60
```
---
```cpp
template <size_t Scaling, typename T>
T round_half_up_unscaled(T value)
```
**Description** |
```cpp
-54 => -5
-55 => -6
-56 => -6
54 => 5
55 => 6
56 => 6
```
## Round Half Down
Values are rounded to the nearest integral value.
'Half' values are rounded down (towards zero).
```cpp
template <size_t Scaling, typename T>
T round_half_down_scaled(T value)
```
**Description** |
```cpp
-54 => -50
-55 => -50
-56 => -60
54 => 50
55 => 50
56 => 60
```
---
```cpp
template <size_t Scaling, typename T>
T round_half_down_unscaled(T value)
```
**Description** |
```cpp
-54 => -5
-55 => -5
-56 => -6
54 => 5
55 => 5
56 => 6
```
---
## Round To Zero
Values are rounded towards zero.
```cpp
template <size_t Scaling, typename T>
T round_zero_scaled(T value)
```
**Description** |
```cpp
-54 => -50
-55 => -50
-56 => -50
54 => 50
55 => 50
56 => 50
```
---
```cpp
template <size_t Scaling, typename T>
T round_zero_unscaled(T value)
```
**Description** |
```cpp
-54 => -5
-55 => -5
-56 => -5
54 => 5
55 => 5
56 => 5
```
## Round To Infinity
Values are rounded towards infinity.
```cpp
template <size_t Scaling, typename T>
T round_infinity_scaled(T value)
```
**Description** |
```cpp
-54 => -60
-55 => -60
-56 => -60
54 => 60
55 => 60
56 => 60
```
---
```cpp
template <size_t Scaling, typename T>
T round_infinity_unscaled(T value)
```
**Description** |
```cpp
-54 => -6
-55 => -6
-56 => -6
54 => 6
55 => 6
56 => 6
```
## Round Half Even (Banker's Rounding)
Values are rounded to the nearest integral value.
'Half' values are rounded to the nearest even value.
```cpp
template <size_t Scaling, typename T>
T round_half_even_scaled(T value)
```
**Description** |
```cpp
-54 => -50
-55 => -60
-56 => -60
-64 => -60
-65 => -60
-66 => -70
54 => 50
55 => 60
56 => 60
64 => 60
65 => 60
66 => 70
```
---
```cpp
template <size_t Scaling, typename T>
T round_half_even_unscaled(T value)
```
**Description** |
```cpp
-54 => -5
-55 => -6
-56 => -6
-64 => -6
-65 => -6
-66 => -7
54 => 5
55 => 6
56 => 6
64 => 6
65 => 6
66 => 7
```
---
## Round Half Odd
Values are rounded to the nearest integral value.
'Half' values are rounded to the nearest odd value.
```cpp
template <size_t Scaling, typename T>
T round_half_even_scaled(T value)
```
**Description** |
```cpp
-54 => -50
-55 => -50
-56 => -60
-64 => -60
-65 => -70
-66 => -70
54 => 50
55 => 50
56 => 60
64 => 60
65 => 70
66 => 70
```
---
```cpp
template <size_t Scaling, typename T>
T round_half_even_unscaled(T value)
```
**Description** |
```cpp
-54 => -5
-55 => -5
-56 => -6
-64 => -6
-65 => -7
-66 => -7
54 => 5
55 => 5
56 => 6
64 => 6
65 => 7
66 => 7
```