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) {...@@ -14,6 +14,7 @@ pub fn fabs(x: var) @typeOf(x) {
14 f16 => fabs16(x),14 f16 => fabs16(x),
15 f32 => fabs32(x),15 f32 => fabs32(x),
16 f64 => fabs64(x),16 f64 => fabs64(x),
17 f128 => fabs128(x),
17 else => @compileError("fabs not implemented for " ++ @typeName(T)),18 else => @compileError("fabs not implemented for " ++ @typeName(T)),
18 };19 };
19}20}
...@@ -36,10 +37,17 @@ fn fabs64(x: f64) f64 {...@@ -36,10 +37,17 @@ fn fabs64(x: f64) f64 {
36 return @bitCast(f64, u);37 return @bitCast(f64, u);
37}38}
3839
40fn fabs128(x: f128) f128 {
41 var u = @bitCast(u128, x);
42 u &= maxInt(u128) >> 1;
43 return @bitCast(f128, u);
44}
45
39test "math.fabs" {46test "math.fabs" {
40 expect(fabs(f16(1.0)) == fabs16(1.0));47 expect(fabs(f16(1.0)) == fabs16(1.0));
41 expect(fabs(f32(1.0)) == fabs32(1.0));48 expect(fabs(f32(1.0)) == fabs32(1.0));
42 expect(fabs(f64(1.0)) == fabs64(1.0));49 expect(fabs(f64(1.0)) == fabs64(1.0));
50 expect(fabs(f128(1.0)) == fabs128(1.0));
43}51}
4452
45test "math.fabs16" {53test "math.fabs16" {
...@@ -57,6 +65,11 @@ test "math.fabs64" {...@@ -57,6 +65,11 @@ test "math.fabs64" {
57 expect(fabs64(-1.0) == 1.0);65 expect(fabs64(-1.0) == 1.0);
58}66}
5967
68test "math.fabs128" {
69 expect(fabs128(1.0) == 1.0);
70 expect(fabs128(-1.0) == 1.0);
71}
72
60test "math.fabs16.special" {73test "math.fabs16.special" {
61 expect(math.isPositiveInf(fabs(math.inf(f16))));74 expect(math.isPositiveInf(fabs(math.inf(f16))));
62 expect(math.isPositiveInf(fabs(-math.inf(f16))));75 expect(math.isPositiveInf(fabs(-math.inf(f16))));
...@@ -74,3 +87,9 @@ test "math.fabs64.special" {...@@ -74,3 +87,9 @@ test "math.fabs64.special" {
74 expect(math.isPositiveInf(fabs(-math.inf(f64))));87 expect(math.isPositiveInf(fabs(-math.inf(f64))));
75 expect(math.isNan(fabs(math.nan(f64))));88 expect(math.isNan(fabs(math.nan(f64))));
76}89}
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);...@@ -51,6 +51,12 @@ pub const nan_f64 = @bitCast(f64, nan_u64);
51pub const inf_u64 = u64(0x7FF << 52);51pub const inf_u64 = u64(0x7FF << 52);
52pub const inf_f64 = @bitCast(f64, inf_u64);52pub 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
54pub const nan = @import("nan.zig").nan;60pub const nan = @import("nan.zig").nan;
55pub const snan = @import("nan.zig").snan;61pub const snan = @import("nan.zig").snan;
56pub const inf = @import("inf.zig").inf;62pub const inf = @import("inf.zig").inf;
...@@ -379,7 +385,7 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t...@@ -379,7 +385,7 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t
379 return u0;385 return u0;
380 }386 }
381 const is_signed = from < 0;387 const is_signed = from < 0;
382 const largest_positive_integer = max(if (from<0) (-from)-1 else from, to); // two's complement388 const largest_positive_integer = max(if (from < 0) (-from) - 1 else from, to); // two's complement
383 const base = log2(largest_positive_integer);389 const base = log2(largest_positive_integer);
384 const upper = (1 << base) - 1;390 const upper = (1 << base) - 1;
385 var magnitude_bits = if (upper >= largest_positive_integer) base else base + 1;391 var magnitude_bits = if (upper >= largest_positive_integer) base else base + 1;
...@@ -752,6 +758,7 @@ test "minInt and maxInt" {...@@ -752,6 +758,7 @@ test "minInt and maxInt" {
752 testing.expect(maxInt(u16) == 65535);758 testing.expect(maxInt(u16) == 65535);
753 testing.expect(maxInt(u32) == 4294967295);759 testing.expect(maxInt(u32) == 4294967295);
754 testing.expect(maxInt(u64) == 18446744073709551615);760 testing.expect(maxInt(u64) == 18446744073709551615);
761 testing.expect(maxInt(u128) == 340282366920938463463374607431768211455);
755762
756 testing.expect(maxInt(i0) == 0);763 testing.expect(maxInt(i0) == 0);
757 testing.expect(maxInt(i1) == 0);764 testing.expect(maxInt(i1) == 0);
...@@ -760,6 +767,7 @@ test "minInt and maxInt" {...@@ -760,6 +767,7 @@ test "minInt and maxInt" {
760 testing.expect(maxInt(i32) == 2147483647);767 testing.expect(maxInt(i32) == 2147483647);
761 testing.expect(maxInt(i63) == 4611686018427387903);768 testing.expect(maxInt(i63) == 4611686018427387903);
762 testing.expect(maxInt(i64) == 9223372036854775807);769 testing.expect(maxInt(i64) == 9223372036854775807);
770 testing.expect(maxInt(i128) == 170141183460469231731687303715884105727);
763771
764 testing.expect(minInt(u0) == 0);772 testing.expect(minInt(u0) == 0);
765 testing.expect(minInt(u1) == 0);773 testing.expect(minInt(u1) == 0);
...@@ -768,6 +776,7 @@ test "minInt and maxInt" {...@@ -768,6 +776,7 @@ test "minInt and maxInt" {
768 testing.expect(minInt(u32) == 0);776 testing.expect(minInt(u32) == 0);
769 testing.expect(minInt(u63) == 0);777 testing.expect(minInt(u63) == 0);
770 testing.expect(minInt(u64) == 0);778 testing.expect(minInt(u64) == 0);
779 testing.expect(minInt(u128) == 0);
771780
772 testing.expect(minInt(i0) == 0);781 testing.expect(minInt(i0) == 0);
773 testing.expect(minInt(i1) == -1);782 testing.expect(minInt(i1) == -1);
...@@ -776,6 +785,7 @@ test "minInt and maxInt" {...@@ -776,6 +785,7 @@ test "minInt and maxInt" {
776 testing.expect(minInt(i32) == -2147483648);785 testing.expect(minInt(i32) == -2147483648);
777 testing.expect(minInt(i63) == -4611686018427387904);786 testing.expect(minInt(i63) == -4611686018427387904);
778 testing.expect(minInt(i64) == -9223372036854775808);787 testing.expect(minInt(i64) == -9223372036854775808);
788 testing.expect(minInt(i128) == -170141183460469231731687303715884105728);
779}789}
780790
781test "max value type" {791test "max value type" {
std/math/inf.zig+4-3
...@@ -3,9 +3,10 @@ const math = std.math;...@@ -3,9 +3,10 @@ const math = std.math;
33
4pub fn inf(comptime T: type) T {4pub fn inf(comptime T: type) T {
5 return switch (T) {5 return switch (T) {
6 f16 => @bitCast(f16, math.inf_u16),6 f16 => math.inf_f16,
7 f32 => @bitCast(f32, math.inf_u32),7 f32 => math.inf_f32,
8 f64 => @bitCast(f64, math.inf_u64),8 f64 => math.inf_f64,
9 f128 => math.inf_f128,
9 else => @compileError("inf not implemented for " ++ @typeName(T)),10 else => @compileError("inf not implemented for " ++ @typeName(T)),
10 };11 };
11}12}
std/math/isinf.zig+22
...@@ -18,6 +18,10 @@ pub fn isInf(x: var) bool {...@@ -18,6 +18,10 @@ pub fn isInf(x: var) bool {
18 const bits = @bitCast(u64, x);18 const bits = @bitCast(u64, x);
19 return bits & (maxInt(u64) >> 1) == (0x7FF << 52);19 return bits & (maxInt(u64) >> 1) == (0x7FF << 52);
20 },20 },
21 f128 => {
22 const bits = @bitCast(u128, x);
23 return bits & (maxInt(u128) >> 1) == (0x7FFF << 112);
24 },
21 else => {25 else => {
22 @compileError("isInf not implemented for " ++ @typeName(T));26 @compileError("isInf not implemented for " ++ @typeName(T));
23 },27 },
...@@ -36,6 +40,9 @@ pub fn isPositiveInf(x: var) bool {...@@ -36,6 +40,9 @@ pub fn isPositiveInf(x: var) bool {
36 f64 => {40 f64 => {
37 return @bitCast(u64, x) == 0x7FF << 52;41 return @bitCast(u64, x) == 0x7FF << 52;
38 },42 },
43 f128 => {
44 return @bitCast(u128, x) == 0x7FFF << 112;
45 },
39 else => {46 else => {
40 @compileError("isPositiveInf not implemented for " ++ @typeName(T));47 @compileError("isPositiveInf not implemented for " ++ @typeName(T));
41 },48 },
...@@ -54,6 +61,9 @@ pub fn isNegativeInf(x: var) bool {...@@ -54,6 +61,9 @@ pub fn isNegativeInf(x: var) bool {
54 f64 => {61 f64 => {
55 return @bitCast(u64, x) == 0xFFF << 52;62 return @bitCast(u64, x) == 0xFFF << 52;
56 },63 },
64 f128 => {
65 return @bitCast(u128, x) == 0xFFFF << 112;
66 },
57 else => {67 else => {
58 @compileError("isNegativeInf not implemented for " ++ @typeName(T));68 @compileError("isNegativeInf not implemented for " ++ @typeName(T));
59 },69 },
...@@ -67,12 +77,16 @@ test "math.isInf" {...@@ -67,12 +77,16 @@ test "math.isInf" {
67 expect(!isInf(f32(-0.0)));77 expect(!isInf(f32(-0.0)));
68 expect(!isInf(f64(0.0)));78 expect(!isInf(f64(0.0)));
69 expect(!isInf(f64(-0.0)));79 expect(!isInf(f64(-0.0)));
80 expect(!isInf(f128(0.0)));
81 expect(!isInf(f128(-0.0)));
70 expect(isInf(math.inf(f16)));82 expect(isInf(math.inf(f16)));
71 expect(isInf(-math.inf(f16)));83 expect(isInf(-math.inf(f16)));
72 expect(isInf(math.inf(f32)));84 expect(isInf(math.inf(f32)));
73 expect(isInf(-math.inf(f32)));85 expect(isInf(-math.inf(f32)));
74 expect(isInf(math.inf(f64)));86 expect(isInf(math.inf(f64)));
75 expect(isInf(-math.inf(f64)));87 expect(isInf(-math.inf(f64)));
88 expect(isInf(math.inf(f128)));
89 expect(isInf(-math.inf(f128)));
76}90}
7791
78test "math.isPositiveInf" {92test "math.isPositiveInf" {
...@@ -82,12 +96,16 @@ test "math.isPositiveInf" {...@@ -82,12 +96,16 @@ test "math.isPositiveInf" {
82 expect(!isPositiveInf(f32(-0.0)));96 expect(!isPositiveInf(f32(-0.0)));
83 expect(!isPositiveInf(f64(0.0)));97 expect(!isPositiveInf(f64(0.0)));
84 expect(!isPositiveInf(f64(-0.0)));98 expect(!isPositiveInf(f64(-0.0)));
99 expect(!isPositiveInf(f128(0.0)));
100 expect(!isPositiveInf(f128(-0.0)));
85 expect(isPositiveInf(math.inf(f16)));101 expect(isPositiveInf(math.inf(f16)));
86 expect(!isPositiveInf(-math.inf(f16)));102 expect(!isPositiveInf(-math.inf(f16)));
87 expect(isPositiveInf(math.inf(f32)));103 expect(isPositiveInf(math.inf(f32)));
88 expect(!isPositiveInf(-math.inf(f32)));104 expect(!isPositiveInf(-math.inf(f32)));
89 expect(isPositiveInf(math.inf(f64)));105 expect(isPositiveInf(math.inf(f64)));
90 expect(!isPositiveInf(-math.inf(f64)));106 expect(!isPositiveInf(-math.inf(f64)));
107 expect(isPositiveInf(math.inf(f128)));
108 expect(!isPositiveInf(-math.inf(f128)));
91}109}
92110
93test "math.isNegativeInf" {111test "math.isNegativeInf" {
...@@ -97,10 +115,14 @@ test "math.isNegativeInf" {...@@ -97,10 +115,14 @@ test "math.isNegativeInf" {
97 expect(!isNegativeInf(f32(-0.0)));115 expect(!isNegativeInf(f32(-0.0)));
98 expect(!isNegativeInf(f64(0.0)));116 expect(!isNegativeInf(f64(0.0)));
99 expect(!isNegativeInf(f64(-0.0)));117 expect(!isNegativeInf(f64(-0.0)));
118 expect(!isNegativeInf(f128(0.0)));
119 expect(!isNegativeInf(f128(-0.0)));
100 expect(!isNegativeInf(math.inf(f16)));120 expect(!isNegativeInf(math.inf(f16)));
101 expect(isNegativeInf(-math.inf(f16)));121 expect(isNegativeInf(-math.inf(f16)));
102 expect(!isNegativeInf(math.inf(f32)));122 expect(!isNegativeInf(math.inf(f32)));
103 expect(isNegativeInf(-math.inf(f32)));123 expect(isNegativeInf(-math.inf(f32)));
104 expect(!isNegativeInf(math.inf(f64)));124 expect(!isNegativeInf(math.inf(f64)));
105 expect(isNegativeInf(-math.inf(f64)));125 expect(isNegativeInf(-math.inf(f64)));
126 expect(!isNegativeInf(math.inf(f128)));
127 expect(isNegativeInf(-math.inf(f128)));
106}128}
std/math/isnan.zig+6
...@@ -18,6 +18,10 @@ pub fn isNan(x: var) bool {...@@ -18,6 +18,10 @@ pub fn isNan(x: var) bool {
18 const bits = @bitCast(u64, x);18 const bits = @bitCast(u64, x);
19 return (bits & (maxInt(u64) >> 1)) > (u64(0x7FF) << 52);19 return (bits & (maxInt(u64) >> 1)) > (u64(0x7FF) << 52);
20 },20 },
21 f128 => {
22 const bits = @bitCast(u128, x);
23 return (bits & (maxInt(u128) >> 1)) > (u128(0x7FFF) << 112);
24 },
21 else => {25 else => {
22 @compileError("isNan not implemented for " ++ @typeName(T));26 @compileError("isNan not implemented for " ++ @typeName(T));
23 },27 },
...@@ -34,7 +38,9 @@ test "math.isNan" {...@@ -34,7 +38,9 @@ test "math.isNan" {
34 expect(isNan(math.nan(f16)));38 expect(isNan(math.nan(f16)));
35 expect(isNan(math.nan(f32)));39 expect(isNan(math.nan(f32)));
36 expect(isNan(math.nan(f64)));40 expect(isNan(math.nan(f64)));
41 expect(isNan(math.nan(f128)));
37 expect(!isNan(f16(1.0)));42 expect(!isNan(f16(1.0)));
38 expect(!isNan(f32(1.0)));43 expect(!isNan(f32(1.0)));
39 expect(!isNan(f64(1.0)));44 expect(!isNan(f64(1.0)));
45 expect(!isNan(f128(1.0)));
40}46}
std/math/nan.zig+4-3
...@@ -2,9 +2,10 @@ const math = @import("index.zig");...@@ -2,9 +2,10 @@ const math = @import("index.zig");
22
3pub fn nan(comptime T: type) T {3pub fn nan(comptime T: type) T {
4 return switch (T) {4 return switch (T) {
5 f16 => @bitCast(f16, math.nan_u16),5 f16 => math.nan_f16,
6 f32 => @bitCast(f32, math.nan_u32),6 f32 => math.nan_f32,
7 f64 => @bitCast(f64, math.nan_u64),7 f64 => math.nan_f64,
8 f128 => math.nan_f128,
8 else => @compileError("nan not implemented for " ++ @typeName(T)),9 else => @compileError("nan not implemented for " ++ @typeName(T)),
9 };10 };
10}11}