wrap function
Wraps a number into [min, max[ with an always-positive modulo, like a heading wrapping at 360°.
ts
import { wrap } from 'utils';Signature
ts
export function wrap(value: number, min: number, max: number): numberParameters
| Name | Description |
|---|---|
value | The number to wrap. |
min | The included bound. |
max | The excluded bound. |
Returns
The equivalent value in [min, max[.
Example
ts
wrap(370, 0, 360); // 10
wrap(-10, 0, 360); // 350Tests
Line coverage: 100 %.
- ✅ wraps 370 into [0, 360[ as 10
- ✅ wraps -10 into [0, 360[ as 350
- ✅ wraps 360 into [0, 360[ as 0
- ✅ wraps -360 into [0, 360[ as 0
- ✅ wraps -720.5 into [0, 360[ as 359.5
- ✅ wraps 5 into [10, 20[ as 15
- ✅ wraps 25 into [20, 10[ as 15
- ✅ never returns -0
Source
src/math/wrap.ts (on GitHub)
Source code
ts
/**
* Wraps a number into [min, max[ with an always-positive modulo, like a heading wrapping at 360°.
*
* @param value - The number to wrap.
* @param min - The included bound.
* @param max - The excluded bound.
* @returns The equivalent value in [min, max[.
* @example
* wrap(370, 0, 360); // 10
* wrap(-10, 0, 360); // 350
*/
export function wrap(value: number, min: number, max: number): number {
const span = max - min;
return ((((value - min) % span) + span) % span) + min;
}Test file
ts
import { wrap } from './wrap';
describe(wrap, () => {
it.for([
[370, 0, 360, 10],
[-10, 0, 360, 350],
[360, 0, 360, 0],
[-360, 0, 360, 0],
[-720.5, 0, 360, 359.5],
[5, 10, 20, 15],
[25, 20, 10, 15],
] as const)('wraps %s into [%s, %s[ as %s', ([value, min, max, expected]) => {
expect(wrap(value, min, max)).toBe(expected);
});
it('never returns -0', () => {
expect(Object.is(wrap(-360, 0, 360), 0)).toBe(true);
});
});Keywords: wrap, math, function