| author | |
| committer | |
| log | cf007e37b95db9faebf34c4c8f9b73aa20eb0672 |
| tree | 57ff58b87e4fffbfabbf83ce19e83405374ad1d4 |
| parent | be861a85c8a1adc1f82c523136e6d6b18992c372 |
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 | } |
| 38 | 39 | ||
| 40 | fn fabs128(x: f128) f128 { | ||
| 41 | var u = @bitCast(u128, x); | ||
| 42 | u &= maxInt(u128) >> 1; | ||
| 43 | return @bitCast(f128, u); | ||
| 44 | } | ||
| 45 | |||
| 39 | test "math.fabs" { | 46 | test "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 | } |
| 44 | 52 | ||
| 45 | test "math.fabs16" { | 53 | test "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 | } |
| 59 | 67 | ||
| 68 | test "math.fabs128" { | ||
| 69 | expect(fabs128(1.0) == 1.0); | ||
| 70 | expect(fabs128(-1.0) == 1.0); | ||
| 71 | } | ||
| 72 | |||
| 60 | test "math.fabs16.special" { | 73 | test "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 | |||
| 91 | test "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); |
| 51 | pub const inf_u64 = u64(0x7FF << 52); | 51 | pub const inf_u64 = u64(0x7FF << 52); |
| 52 | pub const inf_f64 = @bitCast(f64, inf_u64); | 52 | pub const inf_f64 = @bitCast(f64, inf_u64); |
| 53 | 53 | ||
| 54 | pub const nan_u128 = u128(0x7fff0000000000000000000000000001); | ||
| 55 | pub const nan_f128 = @bitCast(f128, nan_u128); | ||
| 56 | |||
| 57 | pub const inf_u128 = u128(0x7fff0000000000000000000000000000); | ||
| 58 | pub const inf_f128 = @bitCast(f128, inf_u128); | ||
| 59 | |||
| 54 | pub const nan = @import("nan.zig").nan; | 60 | pub const nan = @import("nan.zig").nan; |
| 55 | pub const snan = @import("nan.zig").snan; | 61 | pub const snan = @import("nan.zig").snan; |
| 56 | pub const inf = @import("inf.zig").inf; | 62 | pub 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 complement | 388 | 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); | ||
| 755 | 762 | ||
| 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); | ||
| 763 | 771 | ||
| 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); | ||
| 771 | 780 | ||
| 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 | } |
| 780 | 790 | ||
| 781 | test "max value type" { | 791 | test "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; |
| 3 | 3 | ||
| 4 | pub fn inf(comptime T: type) T { | 4 | pub 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 | } |
| 77 | 91 | ||
| 78 | test "math.isPositiveInf" { | 92 | test "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 | } |
| 92 | 110 | ||
| 93 | test "math.isNegativeInf" { | 111 | test "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"); |
| 2 | 2 | ||
| 3 | pub fn nan(comptime T: type) T { | 3 | pub 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 | } |