Skip to content

Commit 2115d7d

Browse files
MadLittleModsandrewrk
authored andcommitted
Add approxEqAbs support for comptime_float
1 parent faeb0ef commit 2115d7d

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

lib/std/math.zig

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ pub const epsilon = @compileError("Deprecated: use `floatEps` instead");
120120
///
121121
/// NaN values are never considered equal to any value.
122122
pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool {
123-
assert(@typeInfo(T) == .Float);
123+
assert(@typeInfo(T) == .Float or @typeInfo(T) == .ComptimeFloat);
124124
assert(tolerance >= 0);
125125

126126
// Fast path for equal values (and signed zeros and infinites).
@@ -148,7 +148,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool {
148148
///
149149
/// NaN values are never considered equal to any value.
150150
pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool {
151-
assert(@typeInfo(T) == .Float);
151+
assert(@typeInfo(T) == .Float or @typeInfo(T) == .ComptimeFloat);
152152
assert(tolerance > 0);
153153

154154
// Fast path for equal values (and signed zeros and infinites).
@@ -184,6 +184,24 @@ test "approxEqAbs and approxEqRel" {
184184
try testing.expect(approxEqAbs(T, min_value, 0.0, eps_value * 2));
185185
try testing.expect(approxEqAbs(T, -min_value, 0.0, eps_value * 2));
186186
}
187+
188+
comptime {
189+
// `comptime_float` is guaranteed to have the same precision and operations of
190+
// the largest other floating point type, which is f128 but it doesn't have a
191+
// defined layout so we can't rely on `@bitCast` to construct the smallest
192+
// possible epsilon value like we do in the tests above. In the same vein, we
193+
// also can't represent a max/min, `NaN` or `Inf` values.
194+
const eps_value = 1e-4;
195+
const sqrt_eps_value = sqrt(eps_value);
196+
197+
try testing.expect(approxEqAbs(comptime_float, 0.0, 0.0, eps_value));
198+
try testing.expect(approxEqAbs(comptime_float, -0.0, -0.0, eps_value));
199+
try testing.expect(approxEqAbs(comptime_float, 0.0, -0.0, eps_value));
200+
try testing.expect(approxEqRel(comptime_float, 1.0, 1.0, sqrt_eps_value));
201+
try testing.expect(!approxEqRel(comptime_float, 1.0, 0.0, sqrt_eps_value));
202+
try testing.expect(!approxEqAbs(comptime_float, 1.0 + 2 * eps_value, 1.0, eps_value));
203+
try testing.expect(approxEqAbs(comptime_float, 1.0 + 1 * eps_value, 1.0, eps_value));
204+
}
187205
}
188206

189207
pub const doNotOptimizeAway = @compileError("Deprecated: use `std.mem.doNotOptimizeAway` instead");

0 commit comments

Comments
 (0)