authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-01 18:35:19+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-01 14:30:31-07:00
log6f3d6c1f45edea883bc206b8e60dae3b6b34cbbb
treec9c63cc7eb40c163f15b5a2178a7d1b1e438a175
parent2957433b25373dccc336492f6817a1cefadb945c

std: Fix expectWithinEpsilon with negative values


1 files changed, 21 insertions(+), 9 deletions(-)

lib/std/testing.zig+21-9
...@@ -4,6 +4,7 @@...@@ -4,6 +4,7 @@
4// The MIT license requires this copyright notice to be included in all copies4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.5// and substantial portions of the software.
6const std = @import("std.zig");6const std = @import("std.zig");
7const math = std.math;
7const print = std.debug.print;8const print = std.debug.print;
89
9pub const FailingAllocator = @import("testing/failing_allocator.zig").FailingAllocator;10pub const FailingAllocator = @import("testing/failing_allocator.zig").FailingAllocator;
...@@ -198,11 +199,16 @@ pub fn expectWithinMargin(expected: anytype, actual: @TypeOf(expected), margin:...@@ -198,11 +199,16 @@ pub fn expectWithinMargin(expected: anytype, actual: @TypeOf(expected), margin:
198 }199 }
199}200}
200201
201test "expectWithinMargin.f32" {202test "expectWithinMargin" {
202 const x: f32 = 12.0;203 inline for ([_]type{ f16, f32, f64, f128 }) |T| {
203 const y: f32 = 12.06;204 const pos_x: T = 12.0;
205 const pos_y: T = 12.06;
206 const neg_x: T = -12.0;
207 const neg_y: T = -12.06;
204208
205 expectWithinMargin(x, y, 0.1);209 expectWithinMargin(pos_x, pos_y, 0.1);
210 expectWithinMargin(neg_x, neg_y, 0.1);
211 }
206}212}
207213
208/// This function is intended to be used only in tests. When the actual value is not214/// This function is intended to be used only in tests. When the actual value is not
...@@ -212,7 +218,8 @@ test "expectWithinMargin.f32" {...@@ -212,7 +218,8 @@ test "expectWithinMargin.f32" {
212pub fn expectWithinEpsilon(expected: anytype, actual: @TypeOf(expected), epsilon: @TypeOf(expected)) void {218pub fn expectWithinEpsilon(expected: anytype, actual: @TypeOf(expected), epsilon: @TypeOf(expected)) void {
213 std.debug.assert(epsilon >= 0.0 and epsilon <= 1.0);219 std.debug.assert(epsilon >= 0.0 and epsilon <= 1.0);
214220
215 const margin = epsilon * expected;221 // Relative epsilon test.
222 const margin = math.max(math.fabs(expected), math.fabs(actual)) * epsilon;
216 switch (@typeInfo(@TypeOf(actual))) {223 switch (@typeInfo(@TypeOf(actual))) {
217 .Float,224 .Float,
218 .ComptimeFloat,225 .ComptimeFloat,
...@@ -225,11 +232,16 @@ pub fn expectWithinEpsilon(expected: anytype, actual: @TypeOf(expected), epsilon...@@ -225,11 +232,16 @@ pub fn expectWithinEpsilon(expected: anytype, actual: @TypeOf(expected), epsilon
225 }232 }
226}233}
227234
228test "expectWithinEpsilon.f32" {235test "expectWithinEpsilon" {
229 const x: f32 = 12.0;236 inline for ([_]type{ f16, f32, f64, f128 }) |T| {
230 const y: f32 = 13.2;237 const pos_x: T = 12.0;
238 const pos_y: T = 13.2;
239 const neg_x: T = -12.0;
240 const neg_y: T = -13.2;
231241
232 expectWithinEpsilon(x, y, 0.1);242 expectWithinEpsilon(pos_x, pos_y, 0.1);
243 expectWithinEpsilon(neg_x, neg_y, 0.1);
244 }
233}245}
234246
235/// This function is intended to be used only in tests. When the two slices are not247/// This function is intended to be used only in tests. When the two slices are not