authorgravatar for hi@viri.moeviri <hi@viri.moe> 2022-04-07 03:08:42-06:00
committergravatar for hi@viri.moeviri <hi@viri.moe> 2022-04-07 05:04:03-06:00
log5d6a5a123676ada3ccd229f31dc8855aabaf8057
tree1064010b011c3ff2422e167f7186f8e0d85dba82
parentc5c62605341143b19accc00f28af1c46c0a416be
signaturelock-open Commit is signed but in an unrecognized format.

std.math.is*Inf: make generic, support f80


1 files changed, 34 insertions(+), 105 deletions(-)

lib/std/math/isinf.zig+34-105
...@@ -1,131 +1,60 @@...@@ -1,131 +1,60 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const math = std.math;2const math = std.math;
3const expect = std.testing.expect;3const expect = std.testing.expect;
4const maxInt = std.math.maxInt;
54
6/// Returns whether x is an infinity, ignoring sign.5/// Returns whether x is an infinity, ignoring sign.
7pub fn isInf(x: anytype) bool {6pub fn isInf(x: anytype) bool {
8 const T = @TypeOf(x);7 const T = @TypeOf(x);
9 switch (T) {8 const TBits = std.meta.Int(.unsigned, @bitSizeOf(T));
10 f16 => {9 if (@typeInfo(T) != .Float) {
11 const bits = @bitCast(u16, x);10 @compileError("isInf not implemented for " ++ @typeName(T));
12 return bits & 0x7FFF == 0x7C00;
13 },
14 f32 => {
15 const bits = @bitCast(u32, x);
16 return bits & 0x7FFFFFFF == 0x7F800000;
17 },
18 f64 => {
19 const bits = @bitCast(u64, x);
20 return bits & (maxInt(u64) >> 1) == (0x7FF << 52);
21 },
22 f128 => {
23 const bits = @bitCast(u128, x);
24 return bits & (maxInt(u128) >> 1) == (0x7FFF << 112);
25 },
26 else => {
27 @compileError("isInf not implemented for " ++ @typeName(T));
28 },
29 }11 }
12 const remove_sign = ~@as(TBits, 0) >> 1;
13 return @bitCast(TBits, x) & remove_sign == @bitCast(TBits, math.inf(T));
30}14}
3115
32/// Returns whether x is an infinity with a positive sign.16/// Returns whether x is an infinity with a positive sign.
33pub fn isPositiveInf(x: anytype) bool {17pub fn isPositiveInf(x: anytype) bool {
34 const T = @TypeOf(x);18 return x == math.inf(@TypeOf(x));
35 switch (T) {
36 f16 => {
37 return @bitCast(u16, x) == 0x7C00;
38 },
39 f32 => {
40 return @bitCast(u32, x) == 0x7F800000;
41 },
42 f64 => {
43 return @bitCast(u64, x) == 0x7FF << 52;
44 },
45 f128 => {
46 return @bitCast(u128, x) == 0x7FFF << 112;
47 },
48 else => {
49 @compileError("isPositiveInf not implemented for " ++ @typeName(T));
50 },
51 }
52}19}
5320
54/// Returns whether x is an infinity with a negative sign.21/// Returns whether x is an infinity with a negative sign.
55pub fn isNegativeInf(x: anytype) bool {22pub fn isNegativeInf(x: anytype) bool {
56 const T = @TypeOf(x);23 return x == -math.inf(@TypeOf(x));
57 switch (T) {
58 f16 => {
59 return @bitCast(u16, x) == 0xFC00;
60 },
61 f32 => {
62 return @bitCast(u32, x) == 0xFF800000;
63 },
64 f64 => {
65 return @bitCast(u64, x) == 0xFFF << 52;
66 },
67 f128 => {
68 return @bitCast(u128, x) == 0xFFFF << 112;
69 },
70 else => {
71 @compileError("isNegativeInf not implemented for " ++ @typeName(T));
72 },
73 }
74}24}
7525
76test "math.isInf" {26test "math.isInf" {
77 try expect(!isInf(@as(f16, 0.0)));27 // TODO remove when #11391 is resolved
78 try expect(!isInf(@as(f16, -0.0)));28 if (@import("builtin").os.tag == .freebsd) return error.SkipZigTest;
79 try expect(!isInf(@as(f32, 0.0)));29
80 try expect(!isInf(@as(f32, -0.0)));30 inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
81 try expect(!isInf(@as(f64, 0.0)));31 try expect(!isInf(@as(T, 0.0)));
82 try expect(!isInf(@as(f64, -0.0)));32 try expect(!isInf(@as(T, -0.0)));
83 try expect(!isInf(@as(f128, 0.0)));33 try expect(isInf(math.inf(T)));
84 try expect(!isInf(@as(f128, -0.0)));34 try expect(isInf(-math.inf(T)));
85 try expect(isInf(math.inf(f16)));35 }
86 try expect(isInf(-math.inf(f16)));
87 try expect(isInf(math.inf(f32)));
88 try expect(isInf(-math.inf(f32)));
89 try expect(isInf(math.inf(f64)));
90 try expect(isInf(-math.inf(f64)));
91 try expect(isInf(math.inf(f128)));
92 try expect(isInf(-math.inf(f128)));
93}36}
9437
95test "math.isPositiveInf" {38test "math.isPositiveInf" {
96 try expect(!isPositiveInf(@as(f16, 0.0)));39 // TODO remove when #11391 is resolved
97 try expect(!isPositiveInf(@as(f16, -0.0)));40 if (@import("builtin").os.tag == .freebsd) return error.SkipZigTest;
98 try expect(!isPositiveInf(@as(f32, 0.0)));41
99 try expect(!isPositiveInf(@as(f32, -0.0)));42 inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
100 try expect(!isPositiveInf(@as(f64, 0.0)));43 try expect(!isPositiveInf(@as(T, 0.0)));
101 try expect(!isPositiveInf(@as(f64, -0.0)));44 try expect(!isPositiveInf(@as(T, -0.0)));
102 try expect(!isPositiveInf(@as(f128, 0.0)));45 try expect(isPositiveInf(math.inf(T)));
103 try expect(!isPositiveInf(@as(f128, -0.0)));46 try expect(!isPositiveInf(-math.inf(T)));
104 try expect(isPositiveInf(math.inf(f16)));47 }
105 try expect(!isPositiveInf(-math.inf(f16)));
106 try expect(isPositiveInf(math.inf(f32)));
107 try expect(!isPositiveInf(-math.inf(f32)));
108 try expect(isPositiveInf(math.inf(f64)));
109 try expect(!isPositiveInf(-math.inf(f64)));
110 try expect(isPositiveInf(math.inf(f128)));
111 try expect(!isPositiveInf(-math.inf(f128)));
112}48}
11349
114test "math.isNegativeInf" {50test "math.isNegativeInf" {
115 try expect(!isNegativeInf(@as(f16, 0.0)));51 // TODO remove when #11391 is resolved
116 try expect(!isNegativeInf(@as(f16, -0.0)));52 if (@import("builtin").os.tag == .freebsd) return error.SkipZigTest;
117 try expect(!isNegativeInf(@as(f32, 0.0)));53
118 try expect(!isNegativeInf(@as(f32, -0.0)));54 inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
119 try expect(!isNegativeInf(@as(f64, 0.0)));55 try expect(!isNegativeInf(@as(T, 0.0)));
120 try expect(!isNegativeInf(@as(f64, -0.0)));56 try expect(!isNegativeInf(@as(T, -0.0)));
121 try expect(!isNegativeInf(@as(f128, 0.0)));57 try expect(!isNegativeInf(math.inf(T)));
122 try expect(!isNegativeInf(@as(f128, -0.0)));58 try expect(isNegativeInf(-math.inf(T)));
123 try expect(!isNegativeInf(math.inf(f16)));59 }
124 try expect(isNegativeInf(-math.inf(f16)));
125 try expect(!isNegativeInf(math.inf(f32)));
126 try expect(isNegativeInf(-math.inf(f32)));
127 try expect(!isNegativeInf(math.inf(f64)));
128 try expect(isNegativeInf(-math.inf(f64)));
129 try expect(!isNegativeInf(math.inf(f128)));
130 try expect(isNegativeInf(-math.inf(f128)));
131}60}