0
# Precision Control
1
2
Functions for controlling numerical precision, rounding to specific increments, and handling floating-point precision issues.
3
4
## Capabilities
5
6
### Modulo and Fractional Operations
7
8
Functions for modular arithmetic and extracting fractional parts.
9
10
```typescript { .api }
11
/**
12
* GLSL-style modulo: a - b * floor(a / b)
13
* Different from JavaScript % operator which uses truncation
14
* @param a - Dividend
15
* @param b - Divisor
16
* @returns GLSL-style modulo result
17
*/
18
function mod(a: number, b: number): number;
19
20
/**
21
* Returns fractional part of x (equivalent to x - floor(x))
22
* @param x - Input value
23
* @returns Fractional part in range [0, 1)
24
*/
25
function fract(x: number): number;
26
27
/**
28
* Truncates x towards zero (removes fractional part)
29
* @param x - Input value
30
* @returns Integer part of x
31
*/
32
function trunc(x: number): number;
33
```
34
35
**Usage Examples:**
36
37
```typescript
38
import { mod, fract, trunc } from "@thi.ng/math/prec";
39
40
// GLSL-style modulo (always positive result)
41
const glslMod = mod(-3, 2); // 1 (not -1 like JS %)
42
const jsMod = -3 % 2; // -1 (JavaScript behavior)
43
44
// Extract fractional part
45
const fractional = fract(3.14159); // 0.14159
46
const wholePart = trunc(3.14159); // 3
47
48
// Useful for wrapping textures coordinates
49
const wrappedU = fract(2.7); // 0.7 (wrapped texture coordinate)
50
```
51
52
### Precision Rounding
53
54
Functions for rounding to specific increments and precision levels.
55
56
```typescript { .api }
57
/**
58
* Rounds x to nearest multiple of prec
59
* @param x - Value to round
60
* @param prec - Precision increment (default: 1)
61
* @returns Value rounded to nearest multiple of prec
62
*/
63
function roundTo(x: number, prec?: number): number;
64
65
/**
66
* Floors x to nearest multiple of prec
67
* @param x - Value to floor
68
* @param prec - Precision increment (default: 1)
69
* @returns Value floored to multiple of prec
70
*/
71
function floorTo(x: number, prec?: number): number;
72
73
/**
74
* Ceils x to nearest multiple of prec
75
* @param x - Value to ceil
76
* @param prec - Precision increment (default: 1)
77
* @returns Value ceiled to multiple of prec
78
*/
79
function ceilTo(x: number, prec?: number): number;
80
81
/**
82
* Only rounds x if fractional part is within epsilon of 0 or 1
83
* Helps avoid floating-point precision issues
84
* @param x - Value to conditionally round
85
* @param eps - Epsilon threshold (default: EPS constant)
86
* @returns Rounded value if close to integer, otherwise original value
87
*/
88
function roundEps(x: number, eps?: number): number;
89
```
90
91
**Usage Examples:**
92
93
```typescript
94
import { roundTo, floorTo, ceilTo, roundEps, EPS } from "@thi.ng/math/prec";
95
96
// Round to specific increments
97
const rounded = roundTo(3.14159, 0.01); // 3.14
98
const stepped = roundTo(127, 25); // 125 (nearest multiple of 25)
99
100
// Floor and ceil to increments
101
const floored = floorTo(3.7, 0.5); // 3.5
102
const ceiled = ceilTo(3.1, 0.5); // 3.5
103
104
// Precision-aware rounding
105
const almostInteger = 2.9999999999999996;
106
const cleaned = roundEps(almostInteger); // 3 (within epsilon of integer)
107
const notClose = roundEps(2.5); // 2.5 (not close enough to integer)
108
109
// Grid snapping
110
const snapToGrid = (value: number, gridSize: number) =>
111
roundTo(value, gridSize);
112
113
const snapped = snapToGrid(127.3, 10); // 130
114
```
115
116
## Floating-Point Precision Handling
117
118
```typescript
119
import { roundEps, fract, mod } from "@thi.ng/math/prec";
120
121
// Handle accumulated floating-point errors
122
function cleanupFloat(value: number, precision: number = 1e-10): number {
123
return roundEps(value, precision);
124
}
125
126
// Reliable fractional part extraction
127
function safeFract(x: number): number {
128
const f = fract(x);
129
return cleanupFloat(f);
130
}
131
132
// Animation time cycling with precision cleanup
133
function cycleTime(time: number, duration: number): number {
134
const cycled = mod(time, duration);
135
return cleanupFloat(cycled);
136
}
137
138
// Usage examples
139
const cleanValue = cleanupFloat(0.30000000000000004); // 0.3
140
const safeFractional = safeFract(123.9999999999999); // 0 (cleaned)
141
const animTime = cycleTime(5.0000000001, 2); // 1 (clean cycle)
142
```