authorgravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2019-02-13 23:27:23+13:00
committergravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2019-02-13 23:27:23+13:00
logcf007e37b95db9faebf34c4c8f9b73aa20eb0672
tree57ff58b87e4fffbfabbf83ce19e83405374ad1d4
parentbe861a85c8a1adc1f82c523136e6d6b18992c372

Add f128 support for fabs, isinf, isnan, inf and nan functions


6 files changed, 66 insertions(+), 7 deletions(-)

std/math/fabs.zig+19
......@@ -14,6 +14,7 @@ pub fn fabs(x: var) @typeOf(x) {
1414 f16 => fabs16(x),
1515 f32 => fabs32(x),
1616 f64 => fabs64(x),
17 f128 => fabs128(x),
1718 else => @compileError("fabs not implemented for " ++ @typeName(T)),
1819 };
1920}
......@@ -36,10 +37,17 @@ fn fabs64(x: f64) f64 {
3637 return @bitCast(f64, u);
3738}
3839
40fn fabs128(x: f128) f128 {
41 var u = @bitCast(u128, x);
42 u &= maxInt(u128) >> 1;
43 return @bitCast(f128, u);
44}
45
3946test "math.fabs" {
4047 expect(fabs(f16(1.0)) == fabs16(1.0));
4148 expect(fabs(f32(1.0)) == fabs32(1.0));
4249 expect(fabs(f64(1.0)) == fabs64(1.0));
50 expect(fabs(f128(1.0)) == fabs128(1.0));
4351}
4452
4553test "math.fabs16" {
......@@ -57,6 +65,11 @@ test "math.fabs64" {
5765 expect(fabs64(-1.0) == 1.0);
5866}
5967
68test "math.fabs128" {
69 expect(fabs128(1.0) == 1.0);
70 expect(fabs128(-1.0) == 1.0);
71}
72
6073test "math.fabs16.special" {
6174 expect(math.isPositiveInf(fabs(math.inf(f16))));
6275 expect(math.isPositiveInf(fabs(-math.inf(f16))));
......@@ -74,3 +87,9 @@ test "math.fabs64.special" {
7487 expect(math.isPositiveInf(fabs(-math.inf(f64))));
7588 expect(math.isNan(fabs(math.nan(f64))));
7689}
90
91test "math.fabs128.special" {
92 expect(math.isPositiveInf(fabs(math.inf(f128))));
93 expect(math.isPositiveInf(fabs(-math.inf(f128))));
94 expect(math.isNan(fabs(math.nan(f128))));
95}
std/math/index.zig+11-1
......@@ -51,6 +51,12 @@ pub const nan_f64 = @bitCast(f64, nan_u64);
5151pub const inf_u64 = u64(0x7FF << 52);
5252pub const inf_f64 = @bitCast(f64, inf_u64);
5353
54pub const nan_u128 = u128(0x7fff0000000000000000000000000001);
55pub const nan_f128 = @bitCast(f128, nan_u128);
56
57pub const inf_u128 = u128(0x7fff0000000000000000000000000000);
58pub const inf_f128 = @bitCast(f128, inf_u128);
59
5460pub const nan = @import("nan.zig").nan;
5561pub const snan = @import("nan.zig").snan;
5662pub const inf = @import("inf.zig").inf;
......@@ -379,7 +385,7 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t
379385 return u0;
380386 }
381387 const is_signed = from < 0;
382 const largest_positive_integer = max(if (from<0) (-from)-1 else from, to); // two's complement
388 const largest_positive_integer = max(if (from < 0) (-from) - 1 else from, to); // two's complement
383389 const base = log2(largest_positive_integer);
384390 const upper = (1 << base) - 1;
385391 var magnitude_bits = if (upper >= largest_positive_integer) base else base + 1;
......@@ -752,6 +758,7 @@ test "minInt and maxInt" {
752758 testing.expect(maxInt(u16) == 65535);
753759 testing.expect(maxInt(u32) == 4294967295);
754760 testing.expect(maxInt(u64) == 18446744073709551615);
761 testing.expect(maxInt(u128) == 340282366920938463463374607431768211455);
755762
756763 testing.expect(maxInt(i0) == 0);
757764 testing.expect(maxInt(i1) == 0);
......@@ -760,6 +767,7 @@ test "minInt and maxInt" {
760767 testing.expect(maxInt(i32) == 2147483647);
761768 testing.expect(maxInt(i63) == 4611686018427387903);
762769 testing.expect(maxInt(i64) == 9223372036854775807);
770 testing.expect(maxInt(i128) == 170141183460469231731687303715884105727);
763771
764772 testing.expect(minInt(u0) == 0);
765773 testing.expect(minInt(u1) == 0);
......@@ -768,6 +776,7 @@ test "minInt and maxInt" {
768776 testing.expect(minInt(u32) == 0);
769777 testing.expect(minInt(u63) == 0);
770778 testing.expect(minInt(u64) == 0);
779 testing.expect(minInt(u128) == 0);
771780
772781 testing.expect(minInt(i0) == 0);
773782 testing.expect(minInt(i1) == -1);
......@@ -776,6 +785,7 @@ test "minInt and maxInt" {
776785 testing.expect(minInt(i32) == -2147483648);
777786 testing.expect(minInt(i63) == -4611686018427387904);
778787 testing.expect(minInt(i64) == -9223372036854775808);
788 testing.expect(minInt(i128) == -170141183460469231731687303715884105728);
779789}
780790
781791test "max value type" {
std/math/inf.zig+4-3
......@@ -3,9 +3,10 @@ const math = std.math;
33
44pub fn inf(comptime T: type) T {
55 return switch (T) {
6 f16 => @bitCast(f16, math.inf_u16),
7 f32 => @bitCast(f32, math.inf_u32),
8 f64 => @bitCast(f64, math.inf_u64),
6 f16 => math.inf_f16,
7 f32 => math.inf_f32,
8 f64 => math.inf_f64,
9 f128 => math.inf_f128,
910 else => @compileError("inf not implemented for " ++ @typeName(T)),
1011 };
1112}
std/math/isinf.zig+22
......@@ -18,6 +18,10 @@ pub fn isInf(x: var) bool {
1818 const bits = @bitCast(u64, x);
1919 return bits & (maxInt(u64) >> 1) == (0x7FF << 52);
2020 },
21 f128 => {
22 const bits = @bitCast(u128, x);
23 return bits & (maxInt(u128) >> 1) == (0x7FFF << 112);
24 },
2125 else => {
2226 @compileError("isInf not implemented for " ++ @typeName(T));
2327 },
......@@ -36,6 +40,9 @@ pub fn isPositiveInf(x: var) bool {
3640 f64 => {
3741 return @bitCast(u64, x) == 0x7FF << 52;
3842 },
43 f128 => {
44 return @bitCast(u128, x) == 0x7FFF << 112;
45 },
3946 else => {
4047 @compileError("isPositiveInf not implemented for " ++ @typeName(T));
4148 },
......@@ -54,6 +61,9 @@ pub fn isNegativeInf(x: var) bool {
5461 f64 => {
5562 return @bitCast(u64, x) == 0xFFF << 52;
5663 },
64 f128 => {
65 return @bitCast(u128, x) == 0xFFFF << 112;
66 },
5767 else => {
5868 @compileError("isNegativeInf not implemented for " ++ @typeName(T));
5969 },
......@@ -67,12 +77,16 @@ test "math.isInf" {
6777 expect(!isInf(f32(-0.0)));
6878 expect(!isInf(f64(0.0)));
6979 expect(!isInf(f64(-0.0)));
80 expect(!isInf(f128(0.0)));
81 expect(!isInf(f128(-0.0)));
7082 expect(isInf(math.inf(f16)));
7183 expect(isInf(-math.inf(f16)));
7284 expect(isInf(math.inf(f32)));
7385 expect(isInf(-math.inf(f32)));
7486 expect(isInf(math.inf(f64)));
7587 expect(isInf(-math.inf(f64)));
88 expect(isInf(math.inf(f128)));
89 expect(isInf(-math.inf(f128)));
7690}
7791
7892test "math.isPositiveInf" {
......@@ -82,12 +96,16 @@ test "math.isPositiveInf" {
8296 expect(!isPositiveInf(f32(-0.0)));
8397 expect(!isPositiveInf(f64(0.0)));
8498 expect(!isPositiveInf(f64(-0.0)));
99 expect(!isPositiveInf(f128(0.0)));
100 expect(!isPositiveInf(f128(-0.0)));
85101 expect(isPositiveInf(math.inf(f16)));
86102 expect(!isPositiveInf(-math.inf(f16)));
87103 expect(isPositiveInf(math.inf(f32)));
88104 expect(!isPositiveInf(-math.inf(f32)));
89105 expect(isPositiveInf(math.inf(f64)));
90106 expect(!isPositiveInf(-math.inf(f64)));
107 expect(isPositiveInf(math.inf(f128)));
108 expect(!isPositiveInf(-math.inf(f128)));
91109}
92110
93111test "math.isNegativeInf" {
......@@ -97,10 +115,14 @@ test "math.isNegativeInf" {
97115 expect(!isNegativeInf(f32(-0.0)));
98116 expect(!isNegativeInf(f64(0.0)));
99117 expect(!isNegativeInf(f64(-0.0)));
118 expect(!isNegativeInf(f128(0.0)));
119 expect(!isNegativeInf(f128(-0.0)));
100120 expect(!isNegativeInf(math.inf(f16)));
101121 expect(isNegativeInf(-math.inf(f16)));
102122 expect(!isNegativeInf(math.inf(f32)));
103123 expect(isNegativeInf(-math.inf(f32)));
104124 expect(!isNegativeInf(math.inf(f64)));
105125 expect(isNegativeInf(-math.inf(f64)));
126 expect(!isNegativeInf(math.inf(f128)));
127 expect(isNegativeInf(-math.inf(f128)));
106128}
std/math/isnan.zig+6
......@@ -18,6 +18,10 @@ pub fn isNan(x: var) bool {
1818 const bits = @bitCast(u64, x);
1919 return (bits & (maxInt(u64) >> 1)) > (u64(0x7FF) << 52);
2020 },
21 f128 => {
22 const bits = @bitCast(u128, x);
23 return (bits & (maxInt(u128) >> 1)) > (u128(0x7FFF) << 112);
24 },
2125 else => {
2226 @compileError("isNan not implemented for " ++ @typeName(T));
2327 },
......@@ -34,7 +38,9 @@ test "math.isNan" {
3438 expect(isNan(math.nan(f16)));
3539 expect(isNan(math.nan(f32)));
3640 expect(isNan(math.nan(f64)));
41 expect(isNan(math.nan(f128)));
3742 expect(!isNan(f16(1.0)));
3843 expect(!isNan(f32(1.0)));
3944 expect(!isNan(f64(1.0)));
45 expect(!isNan(f128(1.0)));
4046}
std/math/nan.zig+4-3
......@@ -2,9 +2,10 @@ const math = @import("index.zig");
22
33pub fn nan(comptime T: type) T {
44 return switch (T) {
5 f16 => @bitCast(f16, math.nan_u16),
6 f32 => @bitCast(f32, math.nan_u32),
7 f64 => @bitCast(f64, math.nan_u64),
5 f16 => math.nan_f16,
6 f32 => math.nan_f32,
7 f64 => math.nan_f64,
8 f128 => math.nan_f128,
89 else => @compileError("nan not implemented for " ++ @typeName(T)),
910 };
1011}