| author | |
| committer | |
| log | e72049bc61eedd2b7381b87b530428a83581cafe |
| tree | 304d5c71d9338e8150e516ecd6278e26cdc7e3e7 |
| parent | b2ed2c4d4fcc91980118e875b753eb82c7061bb7 |
11 files changed, 75 insertions(+), 32 deletions(-)
lib/std/json/dynamic_test.zig+1-1| ... | ... | @@ -347,7 +347,7 @@ test "negative zero" { |
| 347 | 347 | var parsed = try parseFromTokenSource(Value, testing.allocator, &reader, .{}); |
| 348 | 348 | defer parsed.deinit(); |
| 349 | 349 | |
| 350 | try testing.expect(parsed.value.float == 0 and std.math.signbit(parsed.value.float)); | |
| 350 | try testing.expect(std.math.isNegativeZero(parsed.value.float)); | |
| 351 | 351 | } |
| 352 | 352 | |
| 353 | 353 | fn smallBufferJsonReader(allocator: Allocator, io_reader: anytype) JsonReader(16, @TypeOf(io_reader)) { |
lib/std/math.zig+2| ... | ... | @@ -222,6 +222,8 @@ pub const isFinite = @import("math/isfinite.zig").isFinite; |
| 222 | 222 | pub const isInf = @import("math/isinf.zig").isInf; |
| 223 | 223 | pub const isPositiveInf = @import("math/isinf.zig").isPositiveInf; |
| 224 | 224 | pub const isNegativeInf = @import("math/isinf.zig").isNegativeInf; |
| 225 | pub const isPositiveZero = @import("math/iszero.zig").isPositiveZero; | |
| 226 | pub const isNegativeZero = @import("math/iszero.zig").isNegativeZero; | |
| 225 | 227 | pub const isNormal = @import("math/isnormal.zig").isNormal; |
| 226 | 228 | pub const nextAfter = @import("math/nextafter.zig").nextAfter; |
| 227 | 229 | pub const signbit = @import("math/signbit.zig").signbit; |
lib/std/math/asin.zig+4-4| ... | ... | @@ -169,15 +169,15 @@ test "math.asin64" { |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | 171 | test "math.asin32.special" { |
| 172 | try expect(asin32(0.0) == 0.0); | |
| 173 | try expect(asin32(-0.0) == -0.0); | |
| 172 | try expect(math.isPositiveZero(asin32(0.0))); | |
| 173 | try expect(math.isNegativeZero(asin32(-0.0))); | |
| 174 | 174 | try expect(math.isNan(asin32(-2))); |
| 175 | 175 | try expect(math.isNan(asin32(1.5))); |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | 178 | test "math.asin64.special" { |
| 179 | try expect(asin64(0.0) == 0.0); | |
| 180 | try expect(asin64(-0.0) == -0.0); | |
| 179 | try expect(math.isPositiveZero(asin64(0.0))); | |
| 180 | try expect(math.isNegativeZero(asin64(-0.0))); | |
| 181 | 181 | try expect(math.isNan(asin64(-2))); |
| 182 | 182 | try expect(math.isNan(asin64(1.5))); |
| 183 | 183 | } |
lib/std/math/asinh.zig+4-4| ... | ... | @@ -111,16 +111,16 @@ test "math.asinh64" { |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | 113 | test "math.asinh32.special" { |
| 114 | try expect(asinh32(0.0) == 0.0); | |
| 115 | try expect(@as(u32, @bitCast(asinh32(-0.0))) == @as(u32, 0x80000000)); | |
| 114 | try expect(math.isPositiveZero(asinh32(0.0))); | |
| 115 | try expect(math.isNegativeZero(asinh32(-0.0))); | |
| 116 | 116 | try expect(math.isPositiveInf(asinh32(math.inf(f32)))); |
| 117 | 117 | try expect(math.isNegativeInf(asinh32(-math.inf(f32)))); |
| 118 | 118 | try expect(math.isNan(asinh32(math.nan(f32)))); |
| 119 | 119 | } |
| 120 | 120 | |
| 121 | 121 | test "math.asinh64.special" { |
| 122 | try expect(asinh64(0.0) == 0.0); | |
| 123 | try expect(@as(u64, @bitCast(asinh64(-0.0))) == @as(u64, 0x8000000000000000)); | |
| 122 | try expect(math.isPositiveZero(asinh64(0.0))); | |
| 123 | try expect(math.isNegativeZero(asinh64(-0.0))); | |
| 124 | 124 | try expect(math.isPositiveInf(asinh64(math.inf(f64)))); |
| 125 | 125 | try expect(math.isNegativeInf(asinh64(-math.inf(f64)))); |
| 126 | 126 | try expect(math.isNan(asinh64(math.nan(f64)))); |
lib/std/math/atan.zig+4-4| ... | ... | @@ -239,8 +239,8 @@ test "math.atan64" { |
| 239 | 239 | test "math.atan32.special" { |
| 240 | 240 | const epsilon = 0.000001; |
| 241 | 241 | |
| 242 | try expect(atan32(0.0) == 0.0); | |
| 243 | try expect(atan32(-0.0) == -0.0); | |
| 242 | try expect(math.isPositiveZero(atan32(0.0))); | |
| 243 | try expect(math.isNegativeZero(atan32(-0.0))); | |
| 244 | 244 | try expect(math.approxEqAbs(f32, atan32(math.inf(f32)), math.pi / 2.0, epsilon)); |
| 245 | 245 | try expect(math.approxEqAbs(f32, atan32(-math.inf(f32)), -math.pi / 2.0, epsilon)); |
| 246 | 246 | } |
| ... | ... | @@ -248,8 +248,8 @@ test "math.atan32.special" { |
| 248 | 248 | test "math.atan64.special" { |
| 249 | 249 | const epsilon = 0.000001; |
| 250 | 250 | |
| 251 | try expect(atan64(0.0) == 0.0); | |
| 252 | try expect(atan64(-0.0) == -0.0); | |
| 251 | try expect(math.isPositiveZero(atan64(0.0))); | |
| 252 | try expect(math.isNegativeZero(atan64(-0.0))); | |
| 253 | 253 | try expect(math.approxEqAbs(f64, atan64(math.inf(f64)), math.pi / 2.0, epsilon)); |
| 254 | 254 | try expect(math.approxEqAbs(f64, atan64(-math.inf(f64)), -math.pi / 2.0, epsilon)); |
| 255 | 255 | } |
lib/std/math/cbrt.zig+5-5| ... | ... | @@ -127,7 +127,7 @@ test "math.cbrt" { |
| 127 | 127 | test "math.cbrt32" { |
| 128 | 128 | const epsilon = 0.000001; |
| 129 | 129 | |
| 130 | try expect(cbrt32(0.0) == 0.0); | |
| 130 | try expect(math.isPositiveZero(cbrt32(0.0))); | |
| 131 | 131 | try expect(math.approxEqAbs(f32, cbrt32(0.2), 0.584804, epsilon)); |
| 132 | 132 | try expect(math.approxEqAbs(f32, cbrt32(0.8923), 0.962728, epsilon)); |
| 133 | 133 | try expect(math.approxEqAbs(f32, cbrt32(1.5), 1.144714, epsilon)); |
| ... | ... | @@ -138,7 +138,7 @@ test "math.cbrt32" { |
| 138 | 138 | test "math.cbrt64" { |
| 139 | 139 | const epsilon = 0.000001; |
| 140 | 140 | |
| 141 | try expect(cbrt64(0.0) == 0.0); | |
| 141 | try expect(math.isPositiveZero(cbrt64(0.0))); | |
| 142 | 142 | try expect(math.approxEqAbs(f64, cbrt64(0.2), 0.584804, epsilon)); |
| 143 | 143 | try expect(math.approxEqAbs(f64, cbrt64(0.8923), 0.962728, epsilon)); |
| 144 | 144 | try expect(math.approxEqAbs(f64, cbrt64(1.5), 1.144714, epsilon)); |
| ... | ... | @@ -147,7 +147,7 @@ test "math.cbrt64" { |
| 147 | 147 | } |
| 148 | 148 | |
| 149 | 149 | test "math.cbrt.special" { |
| 150 | try expect(cbrt32(0.0) == 0.0); | |
| 150 | try expect(math.isPositiveZero(cbrt32(0.0))); | |
| 151 | 151 | try expect(@as(u32, @bitCast(cbrt32(-0.0))) == @as(u32, 0x80000000)); |
| 152 | 152 | try expect(math.isPositiveInf(cbrt32(math.inf(f32)))); |
| 153 | 153 | try expect(math.isNegativeInf(cbrt32(-math.inf(f32)))); |
| ... | ... | @@ -155,8 +155,8 @@ test "math.cbrt.special" { |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | 157 | test "math.cbrt64.special" { |
| 158 | try expect(cbrt64(0.0) == 0.0); | |
| 159 | try expect(@as(u64, @bitCast(cbrt64(-0.0))) == @as(u64, 0x8000000000000000)); | |
| 158 | try expect(math.isPositiveZero(cbrt64(0.0))); | |
| 159 | try expect(math.isNegativeZero(cbrt64(-0.0))); | |
| 160 | 160 | try expect(math.isPositiveInf(cbrt64(math.inf(f64)))); |
| 161 | 161 | try expect(math.isNegativeInf(cbrt64(-math.inf(f64)))); |
| 162 | 162 | try expect(math.isNan(cbrt64(math.nan(f64)))); |
lib/std/math/expm1.zig+2-2| ... | ... | @@ -293,7 +293,7 @@ test "math.exp1m" { |
| 293 | 293 | test "math.expm1_32" { |
| 294 | 294 | const epsilon = 0.000001; |
| 295 | 295 | |
| 296 | try expect(expm1_32(0.0) == 0.0); | |
| 296 | try expect(math.isPositiveZero(expm1_32(0.0))); | |
| 297 | 297 | try expect(math.approxEqAbs(f32, expm1_32(0.0), 0.0, epsilon)); |
| 298 | 298 | try expect(math.approxEqAbs(f32, expm1_32(0.2), 0.221403, epsilon)); |
| 299 | 299 | try expect(math.approxEqAbs(f32, expm1_32(0.8923), 1.440737, epsilon)); |
| ... | ... | @@ -303,7 +303,7 @@ test "math.expm1_32" { |
| 303 | 303 | test "math.expm1_64" { |
| 304 | 304 | const epsilon = 0.000001; |
| 305 | 305 | |
| 306 | try expect(expm1_64(0.0) == 0.0); | |
| 306 | try expect(math.isPositiveZero(expm1_64(0.0))); | |
| 307 | 307 | try expect(math.approxEqAbs(f64, expm1_64(0.0), 0.0, epsilon)); |
| 308 | 308 | try expect(math.approxEqAbs(f64, expm1_64(0.2), 0.221403, epsilon)); |
| 309 | 309 | try expect(math.approxEqAbs(f64, expm1_64(0.8923), 1.440737, epsilon)); |
lib/std/math/iszero.zig created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | const std = @import("../std.zig"); | |
| 2 | const math = std.math; | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | /// Returns whether x is positive zero. | |
| 6 | pub inline fn isPositiveZero(x: anytype) bool { | |
| 7 | const T = @TypeOf(x); | |
| 8 | const bit_count = @typeInfo(T).Float.bits; | |
| 9 | const TBits = std.meta.Int(.unsigned, bit_count); | |
| 10 | return @as(TBits, @bitCast(x)) == @as(TBits, 0); | |
| 11 | } | |
| 12 | ||
| 13 | /// Returns whether x is negative zero. | |
| 14 | pub inline fn isNegativeZero(x: anytype) bool { | |
| 15 | const T = @TypeOf(x); | |
| 16 | const bit_count = @typeInfo(T).Float.bits; | |
| 17 | const TBits = std.meta.Int(.unsigned, bit_count); | |
| 18 | return @as(TBits, @bitCast(x)) == @as(TBits, 1) << (bit_count - 1); | |
| 19 | } | |
| 20 | ||
| 21 | test isPositiveZero { | |
| 22 | inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| { | |
| 23 | try expect(isPositiveZero(@as(T, 0.0))); | |
| 24 | try expect(!isPositiveZero(@as(T, -0.0))); | |
| 25 | try expect(!isPositiveZero(math.floatMin(T))); | |
| 26 | try expect(!isPositiveZero(math.floatMax(T))); | |
| 27 | try expect(!isPositiveZero(math.inf(T))); | |
| 28 | try expect(!isPositiveZero(-math.inf(T))); | |
| 29 | } | |
| 30 | } | |
| 31 | ||
| 32 | test isNegativeZero { | |
| 33 | inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| { | |
| 34 | try expect(isNegativeZero(@as(T, -0.0))); | |
| 35 | try expect(!isNegativeZero(@as(T, 0.0))); | |
| 36 | try expect(!isNegativeZero(math.floatMin(T))); | |
| 37 | try expect(!isNegativeZero(math.floatMax(T))); | |
| 38 | try expect(!isNegativeZero(math.inf(T))); | |
| 39 | try expect(!isNegativeZero(-math.inf(T))); | |
| 40 | } | |
| 41 | } |
lib/std/math/log1p.zig+4-4| ... | ... | @@ -212,8 +212,8 @@ test "math.log1p_64" { |
| 212 | 212 | |
| 213 | 213 | test "math.log1p_32.special" { |
| 214 | 214 | try expect(math.isPositiveInf(log1p_32(math.inf(f32)))); |
| 215 | try expect(log1p_32(0.0) == 0.0); | |
| 216 | try expect(log1p_32(-0.0) == -0.0); | |
| 215 | try expect(math.isPositiveZero(log1p_32(0.0))); | |
| 216 | try expect(math.isNegativeZero(log1p_32(-0.0))); | |
| 217 | 217 | try expect(math.isNegativeInf(log1p_32(-1.0))); |
| 218 | 218 | try expect(math.isNan(log1p_32(-2.0))); |
| 219 | 219 | try expect(math.isNan(log1p_32(math.nan(f32)))); |
| ... | ... | @@ -221,8 +221,8 @@ test "math.log1p_32.special" { |
| 221 | 221 | |
| 222 | 222 | test "math.log1p_64.special" { |
| 223 | 223 | try expect(math.isPositiveInf(log1p_64(math.inf(f64)))); |
| 224 | try expect(log1p_64(0.0) == 0.0); | |
| 225 | try expect(log1p_64(-0.0) == -0.0); | |
| 224 | try expect(math.isPositiveZero(log1p_64(0.0))); | |
| 225 | try expect(math.isNegativeZero(log1p_64(-0.0))); | |
| 226 | 226 | try expect(math.isNegativeInf(log1p_64(-1.0))); |
| 227 | 227 | try expect(math.isNan(log1p_64(-2.0))); |
| 228 | 228 | try expect(math.isNan(log1p_64(math.nan(f64)))); |
lib/std/math/sinh.zig+4-4| ... | ... | @@ -123,16 +123,16 @@ test "math.sinh64" { |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | 125 | test "math.sinh32.special" { |
| 126 | try expect(sinh32(0.0) == 0.0); | |
| 127 | try expect(sinh32(-0.0) == -0.0); | |
| 126 | try expect(math.isPositiveZero(sinh32(0.0))); | |
| 127 | try expect(math.isNegativeZero(sinh32(-0.0))); | |
| 128 | 128 | try expect(math.isPositiveInf(sinh32(math.inf(f32)))); |
| 129 | 129 | try expect(math.isNegativeInf(sinh32(-math.inf(f32)))); |
| 130 | 130 | try expect(math.isNan(sinh32(math.nan(f32)))); |
| 131 | 131 | } |
| 132 | 132 | |
| 133 | 133 | test "math.sinh64.special" { |
| 134 | try expect(sinh64(0.0) == 0.0); | |
| 135 | try expect(sinh64(-0.0) == -0.0); | |
| 134 | try expect(math.isPositiveZero(sinh64(0.0))); | |
| 135 | try expect(math.isNegativeZero(sinh64(-0.0))); | |
| 136 | 136 | try expect(math.isPositiveInf(sinh64(math.inf(f64)))); |
| 137 | 137 | try expect(math.isNegativeInf(sinh64(-math.inf(f64)))); |
| 138 | 138 | try expect(math.isNan(sinh64(math.nan(f64)))); |
lib/std/math/tanh.zig+4-4| ... | ... | @@ -135,16 +135,16 @@ test "math.tanh64" { |
| 135 | 135 | } |
| 136 | 136 | |
| 137 | 137 | test "math.tanh32.special" { |
| 138 | try expect(tanh32(0.0) == 0.0); | |
| 139 | try expect(tanh32(-0.0) == -0.0); | |
| 138 | try expect(math.isPositiveZero(tanh32(0.0))); | |
| 139 | try expect(math.isNegativeZero(tanh32(-0.0))); | |
| 140 | 140 | try expect(tanh32(math.inf(f32)) == 1.0); |
| 141 | 141 | try expect(tanh32(-math.inf(f32)) == -1.0); |
| 142 | 142 | try expect(math.isNan(tanh32(math.nan(f32)))); |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | 145 | test "math.tanh64.special" { |
| 146 | try expect(tanh64(0.0) == 0.0); | |
| 147 | try expect(tanh64(-0.0) == -0.0); | |
| 146 | try expect(math.isPositiveZero(tanh64(0.0))); | |
| 147 | try expect(math.isNegativeZero(tanh64(-0.0))); | |
| 148 | 148 | try expect(tanh64(math.inf(f64)) == 1.0); |
| 149 | 149 | try expect(tanh64(-math.inf(f64)) == -1.0); |
| 150 | 150 | try expect(math.isNan(tanh64(math.nan(f64)))); |