add behavior tests for f80

This commit is contained in:
Veikka Tuominen 2022-01-20 10:29:24 +02:00 committed by Andrew Kelley
parent f8b204bb18
commit 4411f9c019
6 changed files with 114 additions and 2 deletions

View File

@ -57,7 +57,7 @@ static inline bool zig_f128_isNaN(float128_t *aPtr) {
} }
static inline bool zig_extF80_isNaN(extFloat80_t *aPtr) { static inline bool zig_extF80_isNaN(extFloat80_t *aPtr) {
return aPtr->signExp & 0x7FFF && aPtr->signif; return (aPtr->signExp & 0x7FFF) == 0x7FFF && aPtr->signif & UINT64_C(0x7FFFFFFFFFFFFFFF);
} }
#endif #endif

View File

@ -4,6 +4,7 @@ const math = std.math;
const pi = std.math.pi; const pi = std.math.pi;
const e = std.math.e; const e = std.math.e;
const Vector = std.meta.Vector; const Vector = std.meta.Vector;
const has_f80_rt = @import("builtin").cpu.arch == .x86_64;
const epsilon = 0.000001; const epsilon = 0.000001;
@ -27,6 +28,10 @@ fn testSqrt() !void {
var a: f64 = 25; var a: f64 = 25;
try expect(@sqrt(a) == 5); try expect(@sqrt(a) == 5);
} }
if (has_f80_rt) {
var a: f80 = 25;
try expect(@sqrt(a) == 5);
}
{ {
const a: comptime_float = 25.0; const a: comptime_float = 25.0;
try expect(@sqrt(a) == 5.0); try expect(@sqrt(a) == 5.0);
@ -86,6 +91,10 @@ fn testSin() !void {
var a: f64 = 0; var a: f64 = 0;
try expect(@sin(a) == 0); try expect(@sin(a) == 0);
} }
// {
// var a: f80 = 0;
// try expect(@sin(a) == 0);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
var result = @sin(v); var result = @sin(v);
@ -116,6 +125,10 @@ fn testCos() !void {
var a: f64 = 0; var a: f64 = 0;
try expect(@cos(a) == 1); try expect(@cos(a) == 1);
} }
// {
// var a: f80 = 0;
// try expect(@cos(a) == 1);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
var result = @cos(v); var result = @cos(v);
@ -146,6 +159,10 @@ fn testExp() !void {
var a: f64 = 0; var a: f64 = 0;
try expect(@exp(a) == 1); try expect(@exp(a) == 1);
} }
// {
// var a: f80 = 0;
// try expect(@exp(a) == 1);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
var result = @exp(v); var result = @exp(v);
@ -176,6 +193,10 @@ fn testExp2() !void {
var a: f64 = 2; var a: f64 = 2;
try expect(@exp2(a) == 4); try expect(@exp2(a) == 4);
} }
// {
// var a: f80 = 2;
// try expect(@exp2(a) == 4);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
var result = @exp2(v); var result = @exp2(v);
@ -208,6 +229,10 @@ fn testLog() !void {
var a: f64 = e; var a: f64 = e;
try expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000))); try expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
} }
// {
// var a: f80 = e;
// try expect(@log(a) == 1);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
var result = @log(v); var result = @log(v);
@ -238,6 +263,10 @@ fn testLog2() !void {
var a: f64 = 4; var a: f64 = 4;
try expect(@log2(a) == 2); try expect(@log2(a) == 2);
} }
// {
// var a: f80 = 4;
// try expect(@log2(a) == 2);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
var result = @log2(v); var result = @log2(v);
@ -268,6 +297,10 @@ fn testLog10() !void {
var a: f64 = 1000; var a: f64 = 1000;
try expect(@log10(a) == 3); try expect(@log10(a) == 3);
} }
// {
// var a: f80 = 1000;
// try expect(@log10(a) == 3);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
var result = @log10(v); var result = @log10(v);
@ -304,6 +337,12 @@ fn testFabs() !void {
try expect(@fabs(a) == 2.5); try expect(@fabs(a) == 2.5);
try expect(@fabs(b) == 2.5); try expect(@fabs(b) == 2.5);
} }
// {
// var a: f80 = -2.5;
// var b: f80 = 2.5;
// try expect(@fabs(a) == 2.5);
// try expect(@fabs(b) == 2.5);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
var result = @fabs(v); var result = @fabs(v);
@ -334,6 +373,10 @@ fn testFloor() !void {
var a: f64 = 3.5; var a: f64 = 3.5;
try expect(@floor(a) == 3); try expect(@floor(a) == 3);
} }
// {
// var a: f80 = 3.5;
// try expect(@floor(a) == 3);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
var result = @floor(v); var result = @floor(v);
@ -364,6 +407,10 @@ fn testCeil() !void {
var a: f64 = 3.5; var a: f64 = 3.5;
try expect(@ceil(a) == 4); try expect(@ceil(a) == 4);
} }
// {
// var a: f80 = 3.5;
// try expect(@ceil(a) == 4);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
var result = @ceil(v); var result = @ceil(v);
@ -394,6 +441,10 @@ fn testTrunc() !void {
var a: f64 = -3.5; var a: f64 = -3.5;
try expect(@trunc(a) == -3); try expect(@trunc(a) == -3);
} }
// {
// var a: f80 = -3.5;
// try expect(@trunc(a) == -3);
// }
{ {
var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
var result = @trunc(v); var result = @trunc(v);
@ -403,3 +454,33 @@ fn testTrunc() !void {
try expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon)); try expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon));
} }
} }
test "floating point comparisons" {
if (has_f80_rt) try testFloatComparisons();
comptime try testFloatComparisons();
}
fn testFloatComparisons() !void {
inline for ([_]type{ f16, f32, f64, f80, f128 }) |ty| {
// No decimal part
{
const x: ty = 1.0;
try expect(x == 1);
try expect(x != 0);
try expect(x > 0);
try expect(x < 2);
try expect(x >= 1);
try expect(x <= 1);
}
// Non-zero decimal part
{
const x: ty = 1.5;
try expect(x != 1);
try expect(x != 2);
try expect(x > 1);
try expect(x < 2);
try expect(x >= 1);
try expect(x <= 2);
}
}
}

View File

@ -5,6 +5,7 @@ const expectEqualSlices = std.testing.expectEqualSlices;
const maxInt = std.math.maxInt; const maxInt = std.math.maxInt;
const minInt = std.math.minInt; const minInt = std.math.minInt;
const mem = std.mem; const mem = std.mem;
const has_f80_rt = @import("builtin").cpu.arch == .x86_64;
test "allow signed integer division/remainder when values are comptime known and positive or exact" { test "allow signed integer division/remainder when values are comptime known and positive or exact" {
try expect(5 / 3 == 1); try expect(5 / 3 == 1);
@ -194,6 +195,8 @@ fn testSqrt(comptime T: type, x: T) !void {
test "@fabs" { test "@fabs" {
try testFabs(f128, 12.0); try testFabs(f128, 12.0);
comptime try testFabs(f128, 12.0); comptime try testFabs(f128, 12.0);
if (has_f80_rt) try testFabs(f80, 12.0);
// comptime try testFabs(f80, 12.0);
try testFabs(f64, 12.0); try testFabs(f64, 12.0);
comptime try testFabs(f64, 12.0); comptime try testFabs(f64, 12.0);
try testFabs(f32, 12.0); try testFabs(f32, 12.0);
@ -217,6 +220,8 @@ test "@floor" {
// FIXME: Generates a floorl function call // FIXME: Generates a floorl function call
// testFloor(f128, 12.0); // testFloor(f128, 12.0);
comptime try testFloor(f128, 12.0); comptime try testFloor(f128, 12.0);
// try testFloor(f80, 12.0);
comptime try testFloor(f80, 12.0);
try testFloor(f64, 12.0); try testFloor(f64, 12.0);
comptime try testFloor(f64, 12.0); comptime try testFloor(f64, 12.0);
try testFloor(f32, 12.0); try testFloor(f32, 12.0);
@ -240,6 +245,8 @@ test "@ceil" {
// FIXME: Generates a ceill function call // FIXME: Generates a ceill function call
//testCeil(f128, 12.0); //testCeil(f128, 12.0);
comptime try testCeil(f128, 12.0); comptime try testCeil(f128, 12.0);
// try testCeil(f80, 12.0);
comptime try testCeil(f80, 12.0);
try testCeil(f64, 12.0); try testCeil(f64, 12.0);
comptime try testCeil(f64, 12.0); comptime try testCeil(f64, 12.0);
try testCeil(f32, 12.0); try testCeil(f32, 12.0);
@ -263,6 +270,14 @@ test "@trunc" {
// FIXME: Generates a truncl function call // FIXME: Generates a truncl function call
//testTrunc(f128, 12.0); //testTrunc(f128, 12.0);
comptime try testTrunc(f128, 12.0); comptime try testTrunc(f128, 12.0);
// try testTrunc(f80, 12.0);
// comptime try testTrunc(f80, 12.0);
comptime {
const x: f80 = 12.0;
const y = x + 0.8;
const z = @trunc(y);
try expectEqual(x, z);
}
try testTrunc(f64, 12.0); try testTrunc(f64, 12.0);
comptime try testTrunc(f64, 12.0); comptime try testTrunc(f64, 12.0);
try testTrunc(f32, 12.0); try testTrunc(f32, 12.0);
@ -294,6 +309,8 @@ test "@round" {
// FIXME: Generates a roundl function call // FIXME: Generates a roundl function call
//testRound(f128, 12.0); //testRound(f128, 12.0);
comptime try testRound(f128, 12.0); comptime try testRound(f128, 12.0);
// try testRound(f80, 12.0);
comptime try testRound(f80, 12.0);
try testRound(f64, 12.0); try testRound(f64, 12.0);
comptime try testRound(f64, 12.0); comptime try testRound(f64, 12.0);
try testRound(f32, 12.0); try testRound(f32, 12.0);
@ -333,10 +350,12 @@ test "NaN comparison" {
try testNanEqNan(f32); try testNanEqNan(f32);
try testNanEqNan(f64); try testNanEqNan(f64);
try testNanEqNan(f128); try testNanEqNan(f128);
if (has_f80_rt) try testNanEqNan(f80);
comptime try testNanEqNan(f16); comptime try testNanEqNan(f16);
comptime try testNanEqNan(f32); comptime try testNanEqNan(f32);
comptime try testNanEqNan(f64); comptime try testNanEqNan(f64);
comptime try testNanEqNan(f128); comptime try testNanEqNan(f128);
// comptime try testNanEqNan(f80);
} }
fn testNanEqNan(comptime F: type) !void { fn testNanEqNan(comptime F: type) !void {

View File

@ -25,6 +25,12 @@ fn testMulAdd() !void {
var c: f64 = 6.25; var c: f64 = 6.25;
try expect(@mulAdd(f64, a, b, c) == 20); try expect(@mulAdd(f64, a, b, c) == 20);
} }
// {
// var a: f16 = 5.5;
// var b: f80 = 2.5;
// var c: f80 = 6.25;
// try expect(@mulAdd(f80, a, b, c) == 20);
// }
if (builtin.os.tag == .macos and builtin.cpu.arch == .aarch64) { if (builtin.os.tag == .macos and builtin.cpu.arch == .aarch64) {
// https://github.com/ziglang/zig/issues/9900 // https://github.com/ziglang/zig/issues/9900
return error.SkipZigTest; return error.SkipZigTest;

View File

@ -13,8 +13,9 @@ test "Type.Float" {
try testing.expect(f16 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 16 } })); try testing.expect(f16 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 16 } }));
try testing.expect(f32 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 32 } })); try testing.expect(f32 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 32 } }));
try testing.expect(f64 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 64 } })); try testing.expect(f64 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 64 } }));
try testing.expect(f80 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 80 } }));
try testing.expect(f128 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 128 } })); try testing.expect(f128 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 128 } }));
try testTypes(&[_]type{ f16, f32, f64, f128 }); try testTypes(&[_]type{ f16, f32, f64, f80, f128 });
} }
test "Type.Array" { test "Type.Array" {

View File

@ -2,6 +2,7 @@ const std = @import("std");
const expect = std.testing.expect; const expect = std.testing.expect;
const mem = std.mem; const mem = std.mem;
const builtin = @import("builtin"); const builtin = @import("builtin");
const has_f80_rt = @import("builtin").cpu.arch == .x86_64;
test "integer widening" { test "integer widening" {
var a: u8 = 250; var a: u8 = 250;
@ -27,6 +28,10 @@ test "float widening" {
try expect(a == b); try expect(a == b);
try expect(b == c); try expect(b == c);
try expect(c == d); try expect(c == d);
if (has_f80_rt) {
var e: f80 = c;
try expect(c == e);
}
} }
test "float widening f16 to f128" { test "float widening f16 to f128" {