1const std = @import("std");
2const math = std.math;
3const testing = std.testing;
4
5const div_f80 = @import("divxf3.zig").div_f80;
6
7const nanRep: u80 = @as(u80, @bitCast(math.nan(f80)));
8const infRep: u80 = @as(u80, @bitCast(math.inf(f80)));
9const negInfRep: u80 = @as(u80, @bitCast(-math.inf(f80)));
10
11fn compareResult(result: f80, expected: u80) bool {
12 const rep: u80 = @bitCast(result);
13
14 if (rep == expected) return true;
15 // test other possible NaN representations (signal NaN)
16 if (math.isNan(result) and math.isNan(@as(f80, @bitCast(expected)))) return true;
17
18 return false;
19}
20
21fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void {
22 const x = div_f80(a, b);
23 const ret = compareResult(x, expected);
24 try testing.expect(ret == true);
25}
26
27fn test__divxf3(a: f80, b: f80) !void {
28 const integerBit = 1 << math.floatFractionalBits(f80);
29 const x = div_f80(a, b);
30
31 // Next float (assuming normal, non-zero result)
32 const x_plus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) + 1) | integerBit);
33 // Prev float (assuming normal, non-zero result)
34 const x_minus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) - 1) | integerBit);
35
36 // Make sure result is more accurate than the adjacent floats
37 const err_x = @abs(@mulAdd(f80, x, b, -a));
38 const err_x_plus_eps = @abs(@mulAdd(f80, x_plus_eps, b, -a));
39 const err_x_minus_eps = @abs(@mulAdd(f80, x_minus_eps, b, -a));
40
41 try testing.expect(err_x_minus_eps > err_x);
42 try testing.expect(err_x_plus_eps > err_x);
43}
44
45test "divxf3" {
46 try expect__divxf3_result(math.nan(f80), 0x1.23456789abcdefp+5, nanRep);
47 try expect__divxf3_result(0x1.23456789abcdefp+5, math.nan(f80), nanRep);
48 try expect__divxf3_result(math.inf(f80), 0x1.23456789abcdefp+5, infRep);
49 try expect__divxf3_result(-math.inf(f80), 0x1.23456789abcdefp+5, negInfRep);
50 try expect__divxf3_result(0x1.23456789abcdefp+5, math.inf(f80), 0x0);
51 try expect__divxf3_result(0x1.23456789abcdefp+5, -math.inf(f80), 0x80000000000000000000);
52 try expect__divxf3_result(math.inf(f80), math.inf(f80), nanRep);
53 try expect__divxf3_result(0.0, 0.0, nanRep);
54 try expect__divxf3_result(-0.0, 0.0, nanRep);
55 try expect__divxf3_result(0.0, 1.0, 0x0);
56 try expect__divxf3_result(-0.0, 1.0, 0x80000000000000000000);
57 try expect__divxf3_result(1.0, 0.0, infRep);
58 try expect__divxf3_result(1.0, -0.0, negInfRep);
59
60 try test__divxf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.eedcbaba3a94546558237654321fp-1);
61 try test__divxf3(0x1.a2b34c56d745382f9abf2c3dfeffp-50, 0x1.ed2c3ba15935332532287654321fp-9);
62 try test__divxf3(0x1.2345f6aaaa786555f42432abcdefp+456, 0x1.edacbba9874f765463544dd3621fp+6400);
63 try test__divxf3(0x1.2d3456f789ba6322bc665544edefp-234, 0x1.eddcdba39f3c8b7a36564354321fp-4455);
64 try test__divxf3(0x1.2345f6b77b7a8953365433abcdefp+234, 0x1.edcba987d6bb3aa467754354321fp-4055);
65 try test__divxf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.a2b34c56d745382f9abf2c3dfeffp-50);
66 try test__divxf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.1234567890abcdef987654321123p0);
67 try test__divxf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.12394205810257120adae8929f23p+16);
68 try test__divxf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.febdcefa1231245f9abf2c3dfeffp-50);
69
70 // Result rounds down to zero
71 try expect__divxf3_result(6.72420628622418701252535563464350521E-4932, 2.0, 0x0);
72}