Merge pull request #11401 from viriuwu/float-category-misc

math: simplify inf (+f80 support), deprecate old constants (followup for #10133)
This commit is contained in:
Andrew Kelley 2022-04-12 06:37:12 -04:00 committed by GitHub
commit 17631cb2d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 264 additions and 353 deletions

View File

@ -444,9 +444,9 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/lib/std/math.zig"
"${CMAKE_SOURCE_DIR}/lib/std/math/big.zig"
"${CMAKE_SOURCE_DIR}/lib/std/math/big/int.zig"
"${CMAKE_SOURCE_DIR}/lib/std/math/float.zig"
"${CMAKE_SOURCE_DIR}/lib/std/math/floor.zig"
"${CMAKE_SOURCE_DIR}/lib/std/math/frexp.zig"
"${CMAKE_SOURCE_DIR}/lib/std/math/inf.zig"
"${CMAKE_SOURCE_DIR}/lib/std/math/isinf.zig"
"${CMAKE_SOURCE_DIR}/lib/std/math/isnan.zig"
"${CMAKE_SOURCE_DIR}/lib/std/math/ln.zig"

View File

@ -2228,8 +2228,8 @@ test "float.special" {
if (builtin.target.cpu.arch != .arm) {
try expectFmt("f64: -nan", "f64: {}", .{-math.nan_f64});
}
try expectFmt("f64: inf", "f64: {}", .{math.inf_f64});
try expectFmt("f64: -inf", "f64: {}", .{-math.inf_f64});
try expectFmt("f64: inf", "f64: {}", .{math.inf(f64)});
try expectFmt("f64: -inf", "f64: {}", .{-math.inf(f64)});
}
test "float.hexadecimal.special" {
@ -2239,8 +2239,8 @@ test "float.hexadecimal.special" {
if (builtin.target.cpu.arch != .arm) {
try expectFmt("f64: -nan", "f64: {x}", .{-math.nan_f64});
}
try expectFmt("f64: inf", "f64: {x}", .{math.inf_f64});
try expectFmt("f64: -inf", "f64: {x}", .{-math.inf_f64});
try expectFmt("f64: inf", "f64: {x}", .{math.inf(f64)});
try expectFmt("f64: -inf", "f64: {x}", .{-math.inf(f64)});
try expectFmt("f64: 0x0.0p0", "f64: {x}", .{@as(f64, 0)});
try expectFmt("f64: -0x0.0p0", "f64: {x}", .{-@as(f64, 0)});
@ -2252,20 +2252,20 @@ test "float.hexadecimal" {
try expectFmt("f64: 0x1.5555555555555p-2", "f64: {x}", .{@as(f64, 1.0 / 3.0)});
try expectFmt("f128: 0x1.5555555555555555555555555555p-2", "f128: {x}", .{@as(f128, 1.0 / 3.0)});
try expectFmt("f16: 0x1p-14", "f16: {x}", .{@as(f16, math.f16_min)});
try expectFmt("f32: 0x1p-126", "f32: {x}", .{@as(f32, math.f32_min)});
try expectFmt("f64: 0x1p-1022", "f64: {x}", .{@as(f64, math.f64_min)});
try expectFmt("f128: 0x1p-16382", "f128: {x}", .{@as(f128, math.f128_min)});
try expectFmt("f16: 0x1p-14", "f16: {x}", .{math.floatMin(f16)});
try expectFmt("f32: 0x1p-126", "f32: {x}", .{math.floatMin(f32)});
try expectFmt("f64: 0x1p-1022", "f64: {x}", .{math.floatMin(f64)});
try expectFmt("f128: 0x1p-16382", "f128: {x}", .{math.floatMin(f128)});
try expectFmt("f16: 0x0.004p-14", "f16: {x}", .{@as(f16, math.f16_true_min)});
try expectFmt("f32: 0x0.000002p-126", "f32: {x}", .{@as(f32, math.f32_true_min)});
try expectFmt("f64: 0x0.0000000000001p-1022", "f64: {x}", .{@as(f64, math.f64_true_min)});
try expectFmt("f128: 0x0.0000000000000000000000000001p-16382", "f128: {x}", .{@as(f128, math.f128_true_min)});
try expectFmt("f16: 0x0.004p-14", "f16: {x}", .{math.floatTrueMin(f16)});
try expectFmt("f32: 0x0.000002p-126", "f32: {x}", .{math.floatTrueMin(f32)});
try expectFmt("f64: 0x0.0000000000001p-1022", "f64: {x}", .{math.floatTrueMin(f64)});
try expectFmt("f128: 0x0.0000000000000000000000000001p-16382", "f128: {x}", .{math.floatTrueMin(f128)});
try expectFmt("f16: 0x1.ffcp15", "f16: {x}", .{@as(f16, math.f16_max)});
try expectFmt("f32: 0x1.fffffep127", "f32: {x}", .{@as(f32, math.f32_max)});
try expectFmt("f64: 0x1.fffffffffffffp1023", "f64: {x}", .{@as(f64, math.f64_max)});
try expectFmt("f128: 0x1.ffffffffffffffffffffffffffffp16383", "f128: {x}", .{@as(f128, math.f128_max)});
try expectFmt("f16: 0x1.ffcp15", "f16: {x}", .{math.floatMax(f16)});
try expectFmt("f32: 0x1.fffffep127", "f32: {x}", .{math.floatMax(f32)});
try expectFmt("f64: 0x1.fffffffffffffp1023", "f64: {x}", .{math.floatMax(f64)});
try expectFmt("f128: 0x1.ffffffffffffffffffffffffffffp16383", "f128: {x}", .{math.floatMax(f128)});
}
test "float.hexadecimal.precision" {

View File

@ -262,14 +262,14 @@ test "f16" {
.{ .s = "0x10p+10", .v = 16384.0 },
.{ .s = "0x10p-10", .v = 0.015625 },
// Max normalized value.
.{ .s = "0x1.ffcp+15", .v = math.f16_max },
.{ .s = "-0x1.ffcp+15", .v = -math.f16_max },
.{ .s = "0x1.ffcp+15", .v = math.floatMax(f16) },
.{ .s = "-0x1.ffcp+15", .v = -math.floatMax(f16) },
// Min normalized value.
.{ .s = "0x1p-14", .v = math.f16_min },
.{ .s = "-0x1p-14", .v = -math.f16_min },
.{ .s = "0x1p-14", .v = math.floatMin(f16) },
.{ .s = "-0x1p-14", .v = -math.floatMin(f16) },
// Min denormal value.
.{ .s = "0x1p-24", .v = math.f16_true_min },
.{ .s = "-0x1p-24", .v = -math.f16_true_min },
.{ .s = "0x1p-24", .v = math.floatTrueMin(f16) },
.{ .s = "-0x1p-24", .v = -math.floatTrueMin(f16) },
};
for (cases) |case| {
@ -286,14 +286,14 @@ test "f32" {
.{ .s = "0x0.ffffffp128", .v = 0x0.ffffffp128 },
.{ .s = "0x0.1234570p-125", .v = 0x0.1234570p-125 },
// Max normalized value.
.{ .s = "0x1.fffffeP+127", .v = math.f32_max },
.{ .s = "-0x1.fffffeP+127", .v = -math.f32_max },
.{ .s = "0x1.fffffeP+127", .v = math.floatMax(f32) },
.{ .s = "-0x1.fffffeP+127", .v = -math.floatMax(f32) },
// Min normalized value.
.{ .s = "0x1p-126", .v = math.f32_min },
.{ .s = "-0x1p-126", .v = -math.f32_min },
.{ .s = "0x1p-126", .v = math.floatMin(f32) },
.{ .s = "-0x1p-126", .v = -math.floatMin(f32) },
// Min denormal value.
.{ .s = "0x1P-149", .v = math.f32_true_min },
.{ .s = "-0x1P-149", .v = -math.f32_true_min },
.{ .s = "0x1P-149", .v = math.floatTrueMin(f32) },
.{ .s = "-0x1P-149", .v = -math.floatTrueMin(f32) },
};
for (cases) |case| {
@ -308,14 +308,14 @@ test "f64" {
.{ .s = "0x10p+10", .v = 16384.0 },
.{ .s = "0x10p-10", .v = 0.015625 },
// Max normalized value.
.{ .s = "0x1.fffffffffffffp+1023", .v = math.f64_max },
.{ .s = "-0x1.fffffffffffffp1023", .v = -math.f64_max },
.{ .s = "0x1.fffffffffffffp+1023", .v = math.floatMax(f64) },
.{ .s = "-0x1.fffffffffffffp1023", .v = -math.floatMax(f64) },
// Min normalized value.
.{ .s = "0x1p-1022", .v = math.f64_min },
.{ .s = "-0x1p-1022", .v = -math.f64_min },
.{ .s = "0x1p-1022", .v = math.floatMin(f64) },
.{ .s = "-0x1p-1022", .v = -math.floatMin(f64) },
// Min denormalized value.
.{ .s = "0x1p-1074", .v = math.f64_true_min },
.{ .s = "-0x1p-1074", .v = -math.f64_true_min },
.{ .s = "0x1p-1074", .v = math.floatTrueMin(f64) },
.{ .s = "-0x1p-1074", .v = -math.floatTrueMin(f64) },
};
for (cases) |case| {
@ -330,14 +330,14 @@ test "f128" {
.{ .s = "0x10p+10", .v = 16384.0 },
.{ .s = "0x10p-10", .v = 0.015625 },
// Max normalized value.
.{ .s = "0xf.fffffffffffffffffffffffffff8p+16380", .v = math.f128_max },
.{ .s = "-0xf.fffffffffffffffffffffffffff8p+16380", .v = -math.f128_max },
.{ .s = "0xf.fffffffffffffffffffffffffff8p+16380", .v = math.floatMax(f128) },
.{ .s = "-0xf.fffffffffffffffffffffffffff8p+16380", .v = -math.floatMax(f128) },
// Min normalized value.
.{ .s = "0x1p-16382", .v = math.f128_min },
.{ .s = "-0x1p-16382", .v = -math.f128_min },
.{ .s = "0x1p-16382", .v = math.floatMin(f128) },
.{ .s = "-0x1p-16382", .v = -math.floatMin(f128) },
// // Min denormalized value.
.{ .s = "0x1p-16494", .v = math.f128_true_min },
.{ .s = "-0x1p-16494", .v = -math.f128_true_min },
.{ .s = "0x1p-16494", .v = math.floatTrueMin(f128) },
.{ .s = "-0x1p-16494", .v = -math.floatTrueMin(f128) },
.{ .s = "0x1.edcb34a235253948765432134674fp-1", .v = 0x1.edcb34a235253948765432134674fp-1 },
};

View File

@ -45,6 +45,7 @@ pub const floatTrueMin = @import("math/float.zig").floatTrueMin;
pub const floatMin = @import("math/float.zig").floatMin;
pub const floatMax = @import("math/float.zig").floatMax;
pub const floatEps = @import("math/float.zig").floatEps;
pub const inf = @import("math/float.zig").inf;
// TODO Replace with @compileError("deprecated for foobar") after 0.10.0 is released.
pub const f16_true_min: comptime_float = floatTrueMin(f16); // prev: 0.000000059604644775390625
@ -72,6 +73,15 @@ pub const f32_toint: comptime_float = 1.0 / f32_epsilon; // same as before
pub const f64_toint: comptime_float = 1.0 / f64_epsilon; // same as before
pub const f80_toint = 1.0 / f80_epsilon; // same as before
pub const f128_toint = 1.0 / f128_epsilon; // same as before
pub const inf_u16 = @bitCast(u16, inf_f16); // prev: @as(u16, 0x7C00)
pub const inf_f16 = inf(f16); // prev: @bitCast(f16, inf_u16)
pub const inf_u32 = @bitCast(u32, inf_f32); // prev: @as(u32, 0x7F800000)
pub const inf_f32 = inf(f32); // prev: @bitCast(f32, inf_u32)
pub const inf_u64 = @bitCast(u64, inf_f64); // prev: @as(u64, 0x7FF << 52)
pub const inf_f64 = inf(f64); // prev: @bitCast(f64, inf_u64)
pub const inf_f80 = inf(f80); // prev: make_f80(F80{ .fraction = 0x8000000000000000, .exp = 0x7fff })
pub const inf_u128 = @bitCast(u128, inf_f128); // prev: @as(u128, 0x7fff0000000000000000000000000000)
pub const inf_f128 = inf(f128); // prev: @bitCast(f128, inf_u128)
pub const epsilon = floatEps;
// End of "soft deprecated" section
@ -81,28 +91,18 @@ pub const nan_f16 = @bitCast(f16, nan_u16);
pub const qnan_u16 = @as(u16, 0x7E00);
pub const qnan_f16 = @bitCast(f16, qnan_u16);
pub const inf_u16 = @as(u16, 0x7C00);
pub const inf_f16 = @bitCast(f16, inf_u16);
pub const nan_u32 = @as(u32, 0x7F800001);
pub const nan_f32 = @bitCast(f32, nan_u32);
pub const qnan_u32 = @as(u32, 0x7FC00000);
pub const qnan_f32 = @bitCast(f32, qnan_u32);
pub const inf_u32 = @as(u32, 0x7F800000);
pub const inf_f32 = @bitCast(f32, inf_u32);
pub const nan_u64 = @as(u64, 0x7FF << 52) | 1;
pub const nan_f64 = @bitCast(f64, nan_u64);
pub const qnan_u64 = @as(u64, 0x7ff8000000000000);
pub const qnan_f64 = @bitCast(f64, qnan_u64);
pub const inf_u64 = @as(u64, 0x7FF << 52);
pub const inf_f64 = @bitCast(f64, inf_u64);
pub const inf_f80 = make_f80(F80{ .fraction = 0x8000000000000000, .exp = 0x7fff });
pub const nan_f80 = make_f80(F80{ .fraction = 0xA000000000000000, .exp = 0x7fff });
pub const qnan_f80 = make_f80(F80{ .fraction = 0xC000000000000000, .exp = 0x7fff });
@ -112,12 +112,8 @@ pub const nan_f128 = @bitCast(f128, nan_u128);
pub const qnan_u128 = @as(u128, 0x7fff8000000000000000000000000000);
pub const qnan_f128 = @bitCast(f128, qnan_u128);
pub const inf_u128 = @as(u128, 0x7fff0000000000000000000000000000);
pub const inf_f128 = @bitCast(f128, inf_u128);
pub const nan = @import("math/nan.zig").nan;
pub const snan = @import("math/nan.zig").snan;
pub const inf = @import("math/inf.zig").inf;
/// Performs an approximate comparison of two floating point values `x` and `y`.
/// Returns true if the absolute difference between them is less or equal than
@ -125,7 +121,7 @@ pub const inf = @import("math/inf.zig").inf;
///
/// The `tolerance` parameter is the absolute tolerance used when determining if
/// the two numbers are close enough; a good value for this parameter is a small
/// multiple of `epsilon(T)`.
/// multiple of `floatEps(T)`.
///
/// Note that this function is recommended for comparing small numbers
/// around zero; using `approxEqRel` is suggested otherwise.
@ -152,7 +148,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool {
///
/// The `tolerance` parameter is the relative tolerance used when determining if
/// the two numbers are close enough; a good value for this parameter is usually
/// `sqrt(epsilon(T))`, meaning that the two numbers are considered equal if at
/// `sqrt(floatEps(T))`, meaning that the two numbers are considered equal if at
/// least half of the digits are equal.
///
/// Note that for comparisons of small numbers around zero this function won't
@ -183,25 +179,19 @@ pub fn approxEq(comptime T: type, x: T, y: T, tolerance: T) bool {
test "approxEqAbs and approxEqRel" {
inline for ([_]type{ f16, f32, f64, f128 }) |T| {
const eps_value = comptime epsilon(T);
const eps_value = comptime floatEps(T);
const sqrt_eps_value = comptime sqrt(eps_value);
const nan_value = comptime nan(T);
const inf_value = comptime inf(T);
const min_value: T = switch (T) {
f16 => f16_min,
f32 => f32_min,
f64 => f64_min,
f128 => f128_min,
else => unreachable,
};
const min_value = comptime floatMin(T);
try testing.expect(approxEqAbs(T, 0.0, 0.0, eps_value));
try testing.expect(approxEqAbs(T, -0.0, -0.0, eps_value));
try testing.expect(approxEqAbs(T, 0.0, -0.0, eps_value));
try testing.expect(approxEqRel(T, 1.0, 1.0, sqrt_eps_value));
try testing.expect(!approxEqRel(T, 1.0, 0.0, sqrt_eps_value));
try testing.expect(!approxEqAbs(T, 1.0 + 2 * epsilon(T), 1.0, eps_value));
try testing.expect(approxEqAbs(T, 1.0 + 1 * epsilon(T), 1.0, eps_value));
try testing.expect(!approxEqAbs(T, 1.0 + 2 * eps_value, 1.0, eps_value));
try testing.expect(approxEqAbs(T, 1.0 + 1 * eps_value, 1.0, eps_value));
try testing.expect(!approxEqRel(T, 1.0, nan_value, sqrt_eps_value));
try testing.expect(!approxEqRel(T, nan_value, nan_value, sqrt_eps_value));
try testing.expect(approxEqRel(T, inf_value, inf_value, sqrt_eps_value));
@ -1197,12 +1187,6 @@ test "lossyCast" {
try testing.expect(lossyCast(u32, @as(f32, maxInt(u32))) == maxInt(u32));
}
test "f64_min" {
const f64_min_u64 = 0x0010000000000000;
const fmin: f64 = f64_min;
try testing.expect(@bitCast(u64, fmin) == f64_min_u64);
}
/// Returns the maximum value of integer type T.
pub fn maxInt(comptime T: type) comptime_int {
const info = @typeInfo(T);

View File

@ -7,7 +7,7 @@ const std = @import("../std.zig");
const __rem_pio2_large = @import("__rem_pio2_large.zig").__rem_pio2_large;
const math = std.math;
const toint = 1.5 / math.epsilon(f64);
const toint = 1.5 / math.floatEps(f64);
// pi/4
const pio4 = 0x1.921fb54442d18p-1;
// invpio2: 53 bits of 2/pi

View File

@ -7,7 +7,7 @@ const std = @import("../std.zig");
const __rem_pio2_large = @import("__rem_pio2_large.zig").__rem_pio2_large;
const math = std.math;
const toint = 1.5 / math.epsilon(f64);
const toint = 1.5 / math.floatEps(f64);
// pi/4
const pio4 = 0x1.921fb6p-1;
// invpio2: 53 bits of 2/pi

View File

@ -62,6 +62,8 @@ fn ceil32(x: f32) f32 {
}
fn ceil64(x: f64) f64 {
const f64_toint = 1.0 / math.floatEps(f64);
const u = @bitCast(u64, x);
const e = (u >> 52) & 0x7FF;
var y: f64 = undefined;
@ -71,9 +73,9 @@ fn ceil64(x: f64) f64 {
}
if (u >> 63 != 0) {
y = x - math.f64_toint + math.f64_toint - x;
y = x - f64_toint + f64_toint - x;
} else {
y = x + math.f64_toint - math.f64_toint - x;
y = x + f64_toint - f64_toint - x;
}
if (e <= 0x3FF - 1) {
@ -91,6 +93,8 @@ fn ceil64(x: f64) f64 {
}
fn ceil128(x: f128) f128 {
const f128_toint = 1.0 / math.floatEps(f128);
const u = @bitCast(u128, x);
const e = (u >> 112) & 0x7FFF;
var y: f128 = undefined;
@ -98,9 +102,9 @@ fn ceil128(x: f128) f128 {
if (e >= 0x3FFF + 112 or x == 0) return x;
if (u >> 127 != 0) {
y = x - math.f128_toint + math.f128_toint - x;
y = x - f128_toint + f128_toint - x;
} else {
y = x + math.f128_toint - math.f128_toint - x;
y = x + f128_toint - f128_toint - x;
}
if (e <= 0x3FFF - 1) {

View File

@ -120,7 +120,7 @@ fn exp64(z: Complex(f64)) Complex(f64) {
}
test "complex.cexp32" {
const tolerance_f32 = math.sqrt(math.epsilon(f32));
const tolerance_f32 = math.sqrt(math.floatEps(f32));
{
const a = Complex(f32).init(5, 3);
@ -140,7 +140,7 @@ test "complex.cexp32" {
}
test "complex.cexp64" {
const tolerance_f64 = math.sqrt(math.epsilon(f64));
const tolerance_f64 = math.sqrt(math.floatEps(f64));
{
const a = Complex(f64).init(5, 3);

View File

@ -79,7 +79,7 @@ fn sinh32(z: Complex(f32)) Complex(f32) {
if (iy >= 0x7f800000) {
return Complex(f32).init(x * x, x * (y - y));
}
return Complex(f32).init(x * math.cos(y), math.inf_f32 * math.sin(y));
return Complex(f32).init(x * math.cos(y), math.inf(f32) * math.sin(y));
}
return Complex(f32).init((x * x) * (y - y), (x + x) * (y - y));
@ -146,7 +146,7 @@ fn sinh64(z: Complex(f64)) Complex(f64) {
if (iy >= 0x7ff00000) {
return Complex(f64).init(x * x, x * (y - y));
}
return Complex(f64).init(x * math.cos(y), math.inf_f64 * math.sin(y));
return Complex(f64).init(x * math.cos(y), math.inf(f64) * math.sin(y));
}
return Complex(f64).init((x * x) * (y - y), (x + x) * (y - y));

View File

@ -92,6 +92,11 @@ pub fn floatEps(comptime T: type) T {
return reconstructFloat(T, -(floatMantissaDigits(T) - 1), mantissaOne(T));
}
/// Returns the value inf for floating point type T.
pub fn inf(comptime T: type) T {
return reconstructFloat(T, floatExponentMax(T) + 1, mantissaOne(T));
}
test "std.math.float" {
inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
// (1 +) for the sign bit, since it is separate from the other bits

View File

@ -98,6 +98,8 @@ fn floor32(x: f32) f32 {
}
fn floor64(x: f64) f64 {
const f64_toint = 1.0 / math.floatEps(f64);
const u = @bitCast(u64, x);
const e = (u >> 52) & 0x7FF;
var y: f64 = undefined;
@ -107,9 +109,9 @@ fn floor64(x: f64) f64 {
}
if (u >> 63 != 0) {
y = x - math.f64_toint + math.f64_toint - x;
y = x - f64_toint + f64_toint - x;
} else {
y = x + math.f64_toint - math.f64_toint - x;
y = x + f64_toint - f64_toint - x;
}
if (e <= 0x3FF - 1) {
@ -127,6 +129,8 @@ fn floor64(x: f64) f64 {
}
fn floor128(x: f128) f128 {
const f128_toint = 1.0 / math.floatEps(f128);
const u = @bitCast(u128, x);
const e = (u >> 112) & 0x7FFF;
var y: f128 = undefined;
@ -134,9 +138,9 @@ fn floor128(x: f128) f128 {
if (e >= 0x3FFF + 112 or x == 0) return x;
if (u >> 127 != 0) {
y = x - math.f128_toint + math.f128_toint - x;
y = x - f128_toint + f128_toint - x;
} else {
y = x + math.f128_toint - math.f128_toint - x;
y = x + f128_toint - f128_toint - x;
}
if (e <= 0x3FFF - 1) {

View File

@ -68,7 +68,7 @@ fn fma64(x: f64, y: f64, z: f64) f64 {
if (spread <= 53 * 2) {
zs = math.scalbn(zs, -spread);
} else {
zs = math.copysign(f64, math.f64_min, zs);
zs = math.copysign(f64, math.floatMin(f64), zs);
}
const xy = dd_mul(xs, ys);
@ -277,7 +277,7 @@ fn fma128(x: f128, y: f128, z: f128) f128 {
if (spread <= 113 * 2) {
zs = math.scalbn(zs, -spread);
} else {
zs = math.copysign(f128, math.f128_min, zs);
zs = math.copysign(f128, math.floatMin(f128), zs);
}
const xy = dd_mul128(xs, ys);

View File

@ -1,14 +0,0 @@
const std = @import("../std.zig");
const math = std.math;
/// Returns value inf for the type T.
pub fn inf(comptime T: type) T {
return switch (T) {
f16 => math.inf_f16,
f32 => math.inf_f32,
f64 => math.inf_f64,
f80 => math.inf_f80,
f128 => math.inf_f128,
else => @compileError("inf not implemented for " ++ @typeName(T)),
};
}

View File

@ -1,59 +1,40 @@
const std = @import("../std.zig");
const math = std.math;
const expect = std.testing.expect;
const maxInt = std.math.maxInt;
/// Returns whether x is a finite value.
pub fn isFinite(x: anytype) bool {
const T = @TypeOf(x);
switch (T) {
f16 => {
const bits = @bitCast(u16, x);
return bits & 0x7FFF < 0x7C00;
},
f32 => {
const bits = @bitCast(u32, x);
return bits & 0x7FFFFFFF < 0x7F800000;
},
f64 => {
const bits = @bitCast(u64, x);
return bits & (maxInt(u64) >> 1) < (0x7FF << 52);
},
f128 => {
const bits = @bitCast(u128, x);
return bits & (maxInt(u128) >> 1) < (0x7FFF << 112);
},
else => {
@compileError("isFinite not implemented for " ++ @typeName(T));
},
const TBits = std.meta.Int(.unsigned, @bitSizeOf(T));
if (@typeInfo(T) != .Float) {
@compileError("isFinite not implemented for " ++ @typeName(T));
}
const remove_sign = ~@as(TBits, 0) >> 1;
return @bitCast(TBits, x) & remove_sign < @bitCast(TBits, math.inf(T));
}
test "math.isFinite" {
try expect(isFinite(@as(f16, 0.0)));
try expect(isFinite(@as(f16, -0.0)));
try expect(isFinite(@as(f32, 0.0)));
try expect(isFinite(@as(f32, -0.0)));
try expect(isFinite(@as(f64, 0.0)));
try expect(isFinite(@as(f64, -0.0)));
try expect(isFinite(@as(f128, 0.0)));
try expect(isFinite(@as(f128, -0.0)));
// TODO remove when #11391 is resolved
if (@import("builtin").os.tag == .freebsd) return error.SkipZigTest;
try expect(!isFinite(math.inf(f16)));
try expect(!isFinite(-math.inf(f16)));
try expect(!isFinite(math.inf(f32)));
try expect(!isFinite(-math.inf(f32)));
try expect(!isFinite(math.inf(f64)));
try expect(!isFinite(-math.inf(f64)));
try expect(!isFinite(math.inf(f128)));
try expect(!isFinite(-math.inf(f128)));
inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
// normals
try expect(isFinite(@as(T, 1.0)));
try expect(isFinite(-@as(T, 1.0)));
try expect(!isFinite(math.nan(f16)));
try expect(!isFinite(-math.nan(f16)));
try expect(!isFinite(math.nan(f32)));
try expect(!isFinite(-math.nan(f32)));
try expect(!isFinite(math.nan(f64)));
try expect(!isFinite(-math.nan(f64)));
try expect(!isFinite(math.nan(f128)));
try expect(!isFinite(-math.nan(f128)));
// zero & subnormals
try expect(isFinite(@as(T, 0.0)));
try expect(isFinite(@as(T, -0.0)));
try expect(isFinite(math.floatTrueMin(T)));
// other float limits
try expect(isFinite(math.floatMin(T)));
try expect(isFinite(math.floatMax(T)));
// inf & nan
try expect(!isFinite(math.inf(T)));
try expect(!isFinite(-math.inf(T)));
try expect(!isFinite(math.nan(T)));
try expect(!isFinite(-math.nan(T)));
}
}

View File

@ -1,131 +1,66 @@
const std = @import("../std.zig");
const math = std.math;
const expect = std.testing.expect;
const maxInt = std.math.maxInt;
/// Returns whether x is an infinity, ignoring sign.
pub fn isInf(x: anytype) bool {
const T = @TypeOf(x);
switch (T) {
f16 => {
const bits = @bitCast(u16, x);
return bits & 0x7FFF == 0x7C00;
},
f32 => {
const bits = @bitCast(u32, x);
return bits & 0x7FFFFFFF == 0x7F800000;
},
f64 => {
const bits = @bitCast(u64, x);
return bits & (maxInt(u64) >> 1) == (0x7FF << 52);
},
f128 => {
const bits = @bitCast(u128, x);
return bits & (maxInt(u128) >> 1) == (0x7FFF << 112);
},
else => {
@compileError("isInf not implemented for " ++ @typeName(T));
},
const TBits = std.meta.Int(.unsigned, @bitSizeOf(T));
if (@typeInfo(T) != .Float) {
@compileError("isInf not implemented for " ++ @typeName(T));
}
const remove_sign = ~@as(TBits, 0) >> 1;
return @bitCast(TBits, x) & remove_sign == @bitCast(TBits, math.inf(T));
}
/// Returns whether x is an infinity with a positive sign.
pub fn isPositiveInf(x: anytype) bool {
const T = @TypeOf(x);
switch (T) {
f16 => {
return @bitCast(u16, x) == 0x7C00;
},
f32 => {
return @bitCast(u32, x) == 0x7F800000;
},
f64 => {
return @bitCast(u64, x) == 0x7FF << 52;
},
f128 => {
return @bitCast(u128, x) == 0x7FFF << 112;
},
else => {
@compileError("isPositiveInf not implemented for " ++ @typeName(T));
},
}
return x == math.inf(@TypeOf(x));
}
/// Returns whether x is an infinity with a negative sign.
pub fn isNegativeInf(x: anytype) bool {
const T = @TypeOf(x);
switch (T) {
f16 => {
return @bitCast(u16, x) == 0xFC00;
},
f32 => {
return @bitCast(u32, x) == 0xFF800000;
},
f64 => {
return @bitCast(u64, x) == 0xFFF << 52;
},
f128 => {
return @bitCast(u128, x) == 0xFFFF << 112;
},
else => {
@compileError("isNegativeInf not implemented for " ++ @typeName(T));
},
}
return x == -math.inf(@TypeOf(x));
}
test "math.isInf" {
try expect(!isInf(@as(f16, 0.0)));
try expect(!isInf(@as(f16, -0.0)));
try expect(!isInf(@as(f32, 0.0)));
try expect(!isInf(@as(f32, -0.0)));
try expect(!isInf(@as(f64, 0.0)));
try expect(!isInf(@as(f64, -0.0)));
try expect(!isInf(@as(f128, 0.0)));
try expect(!isInf(@as(f128, -0.0)));
try expect(isInf(math.inf(f16)));
try expect(isInf(-math.inf(f16)));
try expect(isInf(math.inf(f32)));
try expect(isInf(-math.inf(f32)));
try expect(isInf(math.inf(f64)));
try expect(isInf(-math.inf(f64)));
try expect(isInf(math.inf(f128)));
try expect(isInf(-math.inf(f128)));
// TODO remove when #11391 is resolved
if (@import("builtin").os.tag == .freebsd) return error.SkipZigTest;
inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
try expect(!isInf(@as(T, 0.0)));
try expect(!isInf(@as(T, -0.0)));
try expect(isInf(math.inf(T)));
try expect(isInf(-math.inf(T)));
try expect(!isInf(math.nan(T)));
try expect(!isInf(-math.nan(T)));
}
}
test "math.isPositiveInf" {
try expect(!isPositiveInf(@as(f16, 0.0)));
try expect(!isPositiveInf(@as(f16, -0.0)));
try expect(!isPositiveInf(@as(f32, 0.0)));
try expect(!isPositiveInf(@as(f32, -0.0)));
try expect(!isPositiveInf(@as(f64, 0.0)));
try expect(!isPositiveInf(@as(f64, -0.0)));
try expect(!isPositiveInf(@as(f128, 0.0)));
try expect(!isPositiveInf(@as(f128, -0.0)));
try expect(isPositiveInf(math.inf(f16)));
try expect(!isPositiveInf(-math.inf(f16)));
try expect(isPositiveInf(math.inf(f32)));
try expect(!isPositiveInf(-math.inf(f32)));
try expect(isPositiveInf(math.inf(f64)));
try expect(!isPositiveInf(-math.inf(f64)));
try expect(isPositiveInf(math.inf(f128)));
try expect(!isPositiveInf(-math.inf(f128)));
// TODO remove when #11391 is resolved
if (@import("builtin").os.tag == .freebsd) return error.SkipZigTest;
inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
try expect(!isPositiveInf(@as(T, 0.0)));
try expect(!isPositiveInf(@as(T, -0.0)));
try expect(isPositiveInf(math.inf(T)));
try expect(!isPositiveInf(-math.inf(T)));
try expect(!isInf(math.nan(T)));
try expect(!isInf(-math.nan(T)));
}
}
test "math.isNegativeInf" {
try expect(!isNegativeInf(@as(f16, 0.0)));
try expect(!isNegativeInf(@as(f16, -0.0)));
try expect(!isNegativeInf(@as(f32, 0.0)));
try expect(!isNegativeInf(@as(f32, -0.0)));
try expect(!isNegativeInf(@as(f64, 0.0)));
try expect(!isNegativeInf(@as(f64, -0.0)));
try expect(!isNegativeInf(@as(f128, 0.0)));
try expect(!isNegativeInf(@as(f128, -0.0)));
try expect(!isNegativeInf(math.inf(f16)));
try expect(isNegativeInf(-math.inf(f16)));
try expect(!isNegativeInf(math.inf(f32)));
try expect(isNegativeInf(-math.inf(f32)));
try expect(!isNegativeInf(math.inf(f64)));
try expect(isNegativeInf(-math.inf(f64)));
try expect(!isNegativeInf(math.inf(f128)));
try expect(isNegativeInf(-math.inf(f128)));
// TODO remove when #11391 is resolved
if (@import("builtin").os.tag == .freebsd) return error.SkipZigTest;
inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
try expect(!isNegativeInf(@as(T, 0.0)));
try expect(!isNegativeInf(@as(T, -0.0)));
try expect(!isNegativeInf(math.inf(T)));
try expect(isNegativeInf(-math.inf(T)));
try expect(!isInf(math.nan(T)));
try expect(!isInf(-math.nan(T)));
}
}

View File

@ -57,6 +57,8 @@ pub fn ldexp(x: anytype, n: i32) @TypeOf(x) {
}
test "math.ldexp" {
// TODO derive the various constants here with new maths API
// basic usage
try expect(ldexp(@as(f16, 1.5), 4) == 24.0);
try expect(ldexp(@as(f32, 1.5), 4) == 24.0);
@ -73,20 +75,20 @@ test "math.ldexp" {
try expect(math.isNormal(ldexp(@as(f128, 1.0), -16382)));
try expect(!math.isNormal(ldexp(@as(f128, 1.0), -16383)));
// unreliable due to lack of native f16 support, see talk on PR #8733
// try expect(ldexp(@as(f16, 0x1.1FFp-1), -14 - 9) == math.f16_true_min);
try expect(ldexp(@as(f32, 0x1.3FFFFFp-1), -126 - 22) == math.f32_true_min);
try expect(ldexp(@as(f64, 0x1.7FFFFFFFFFFFFp-1), -1022 - 51) == math.f64_true_min);
try expect(ldexp(@as(f128, 0x1.7FFFFFFFFFFFFFFFFFFFFFFFFFFFp-1), -16382 - 111) == math.f128_true_min);
// try expect(ldexp(@as(f16, 0x1.1FFp-1), -14 - 9) == math.floatTrueMin(f16));
try expect(ldexp(@as(f32, 0x1.3FFFFFp-1), -126 - 22) == math.floatTrueMin(f32));
try expect(ldexp(@as(f64, 0x1.7FFFFFFFFFFFFp-1), -1022 - 51) == math.floatTrueMin(f64));
try expect(ldexp(@as(f128, 0x1.7FFFFFFFFFFFFFFFFFFFFFFFFFFFp-1), -16382 - 111) == math.floatTrueMin(f128));
// float limits
try expect(ldexp(@as(f32, math.f32_max), -128 - 149) > 0.0);
try expect(ldexp(@as(f32, math.f32_max), -128 - 149 - 1) == 0.0);
try expect(!math.isPositiveInf(ldexp(@as(f16, math.f16_true_min), 15 + 24)));
try expect(math.isPositiveInf(ldexp(@as(f16, math.f16_true_min), 15 + 24 + 1)));
try expect(!math.isPositiveInf(ldexp(@as(f32, math.f32_true_min), 127 + 149)));
try expect(math.isPositiveInf(ldexp(@as(f32, math.f32_true_min), 127 + 149 + 1)));
try expect(!math.isPositiveInf(ldexp(@as(f64, math.f64_true_min), 1023 + 1074)));
try expect(math.isPositiveInf(ldexp(@as(f64, math.f64_true_min), 1023 + 1074 + 1)));
try expect(!math.isPositiveInf(ldexp(@as(f128, math.f128_true_min), 16383 + 16494)));
try expect(math.isPositiveInf(ldexp(@as(f128, math.f128_true_min), 16383 + 16494 + 1)));
try expect(ldexp(math.floatMax(f32), -128 - 149) > 0.0);
try expect(ldexp(math.floatMax(f32), -128 - 149 - 1) == 0.0);
try expect(!math.isPositiveInf(ldexp(math.floatTrueMin(f16), 15 + 24)));
try expect(math.isPositiveInf(ldexp(math.floatTrueMin(f16), 15 + 24 + 1)));
try expect(!math.isPositiveInf(ldexp(math.floatTrueMin(f32), 127 + 149)));
try expect(math.isPositiveInf(ldexp(math.floatTrueMin(f32), 127 + 149 + 1)));
try expect(!math.isPositiveInf(ldexp(math.floatTrueMin(f64), 1023 + 1074)));
try expect(math.isPositiveInf(ldexp(math.floatTrueMin(f64), 1023 + 1074 + 1)));
try expect(!math.isPositiveInf(ldexp(math.floatTrueMin(f128), 16383 + 16494)));
try expect(math.isPositiveInf(ldexp(math.floatTrueMin(f128), 16383 + 16494 + 1)));
}

View File

@ -29,6 +29,8 @@ pub fn round(x: anytype) @TypeOf(x) {
}
fn round32(x_: f32) f32 {
const f32_toint = 1.0 / math.floatEps(f32);
var x = x_;
const u = @bitCast(u32, x);
const e = (u >> 23) & 0xFF;
@ -41,11 +43,11 @@ fn round32(x_: f32) f32 {
x = -x;
}
if (e < 0x7F - 1) {
math.doNotOptimizeAway(x + math.f32_toint);
math.doNotOptimizeAway(x + f32_toint);
return 0 * @bitCast(f32, u);
}
y = x + math.f32_toint - math.f32_toint - x;
y = x + f32_toint - f32_toint - x;
if (y > 0.5) {
y = y + x - 1;
} else if (y <= -0.5) {
@ -62,6 +64,8 @@ fn round32(x_: f32) f32 {
}
fn round64(x_: f64) f64 {
const f64_toint = 1.0 / math.floatEps(f64);
var x = x_;
const u = @bitCast(u64, x);
const e = (u >> 52) & 0x7FF;
@ -74,11 +78,11 @@ fn round64(x_: f64) f64 {
x = -x;
}
if (e < 0x3ff - 1) {
math.doNotOptimizeAway(x + math.f64_toint);
math.doNotOptimizeAway(x + f64_toint);
return 0 * @bitCast(f64, u);
}
y = x + math.f64_toint - math.f64_toint - x;
y = x + f64_toint - f64_toint - x;
if (y > 0.5) {
y = y + x - 1;
} else if (y <= -0.5) {
@ -95,6 +99,8 @@ fn round64(x_: f64) f64 {
}
fn round128(x_: f128) f128 {
const f128_toint = 1.0 / math.floatEps(f128);
var x = x_;
const u = @bitCast(u128, x);
const e = (u >> 112) & 0x7FFF;
@ -107,11 +113,11 @@ fn round128(x_: f128) f128 {
x = -x;
}
if (e < 0x3FFF - 1) {
math.doNotOptimizeAway(x + math.f64_toint);
math.doNotOptimizeAway(x + f128_toint);
return 0 * @bitCast(f128, u);
}
y = x + math.f128_toint - math.f128_toint - x;
y = x + f128_toint - f128_toint - x;
if (y > 0.5) {
y = y + x - 1;
} else if (y <= -0.5) {

View File

@ -28,7 +28,7 @@ pub fn next_f64(random: Random, comptime tables: ZigTable) f64 {
} else {
// Generate a value in the range [1, 2) and scale into (0, 1)
const repr = (0x3ff << 52) | (bits >> 12);
break :blk @bitCast(f64, repr) - (1.0 - math.f64_epsilon / 2.0);
break :blk @bitCast(f64, repr) - (1.0 - math.floatEps(f64) / 2.0);
}
};

View File

@ -34,8 +34,12 @@ test "divtf3" {
try test__divtf3(math.qnan_f128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0);
// NaN / any = NaN
try test__divtf3(math.nan_f128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0);
// inf / any = inf
try test__divtf3(math.inf_f128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0);
// inf / any(except inf and nan) = inf
try test__divtf3(math.inf(f128), 0x1.23456789abcdefp+5, 0x7fff000000000000, 0);
// inf / inf = nan
try test__divtf3(math.inf(f128), math.inf(f128), 0x7fff800000000000, 0);
// inf / nan = nan
try test__divtf3(math.inf(f128), math.nan(f128), 0x7fff800000000000, 0);
try test__divtf3(0x1.a23b45362464523375893ab4cdefp+5, 0x1.eedcbaba3a94546558237654321fp-1, 0x4004b0b72924d407, 0x0717e84356c6eba2);
try test__divtf3(0x1.a2b34c56d745382f9abf2c3dfeffp-50, 0x1.ed2c3ba15935332532287654321fp-9, 0x3fd5b2af3f828c9b, 0x40e51f64cde8b1f2);

View File

@ -9,7 +9,7 @@ fn test__fixdfdi(a: f64, expected: i64) !void {
}
test "fixdfdi" {
try test__fixdfdi(-math.f64_max, math.minInt(i64));
try test__fixdfdi(-math.floatMax(f64), math.minInt(i64));
try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
@ -32,9 +32,9 @@ test "fixdfdi" {
try test__fixdfdi(-1.0, -1);
try test__fixdfdi(-0.99, 0);
try test__fixdfdi(-0.5, 0);
try test__fixdfdi(-math.f64_min, 0);
try test__fixdfdi(-math.floatMin(f64), 0);
try test__fixdfdi(0.0, 0);
try test__fixdfdi(math.f64_min, 0);
try test__fixdfdi(math.floatMin(f64), 0);
try test__fixdfdi(0.5, 0);
try test__fixdfdi(0.99, 0);
try test__fixdfdi(1.0, 1);
@ -58,5 +58,5 @@ test "fixdfdi" {
try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
try test__fixdfdi(math.f64_max, math.maxInt(i64));
try test__fixdfdi(math.floatMax(f64), math.maxInt(i64));
}

View File

@ -9,7 +9,7 @@ fn test__fixdfsi(a: f64, expected: i32) !void {
}
test "fixdfsi" {
try test__fixdfsi(-math.f64_max, math.minInt(i32));
try test__fixdfsi(-math.floatMax(f64), math.minInt(i32));
try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
@ -36,9 +36,9 @@ test "fixdfsi" {
try test__fixdfsi(-1.0, -1);
try test__fixdfsi(-0.99, 0);
try test__fixdfsi(-0.5, 0);
try test__fixdfsi(-math.f64_min, 0);
try test__fixdfsi(-math.floatMin(f64), 0);
try test__fixdfsi(0.0, 0);
try test__fixdfsi(math.f64_min, 0);
try test__fixdfsi(math.floatMin(f64), 0);
try test__fixdfsi(0.5, 0);
try test__fixdfsi(0.99, 0);
try test__fixdfsi(1.0, 1);
@ -66,5 +66,5 @@ test "fixdfsi" {
try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
try test__fixdfsi(math.f64_max, math.maxInt(i32));
try test__fixdfsi(math.floatMax(f64), math.maxInt(i32));
}

View File

@ -9,7 +9,7 @@ fn test__fixdfti(a: f64, expected: i128) !void {
}
test "fixdfti" {
try test__fixdfti(-math.f64_max, math.minInt(i128));
try test__fixdfti(-math.floatMax(f64), math.minInt(i128));
try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
@ -32,9 +32,9 @@ test "fixdfti" {
try test__fixdfti(-1.0, -1);
try test__fixdfti(-0.99, 0);
try test__fixdfti(-0.5, 0);
try test__fixdfti(-math.f64_min, 0);
try test__fixdfti(-math.floatMin(f64), 0);
try test__fixdfti(0.0, 0);
try test__fixdfti(math.f64_min, 0);
try test__fixdfti(math.floatMin(f64), 0);
try test__fixdfti(0.5, 0);
try test__fixdfti(0.99, 0);
try test__fixdfti(1.0, 1);
@ -58,5 +58,5 @@ test "fixdfti" {
try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
try test__fixdfti(math.f64_max, math.maxInt(i128));
try test__fixdfti(math.floatMax(f64), math.maxInt(i128));
}

View File

@ -11,49 +11,49 @@ fn test__fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t, expected:
}
test "fixint.i1" {
try test__fixint(f32, i1, -math.inf_f32, -1);
try test__fixint(f32, i1, -math.f32_max, -1);
try test__fixint(f32, i1, -math.inf(f32), -1);
try test__fixint(f32, i1, -math.floatMax(f32), -1);
try test__fixint(f32, i1, -2.0, -1);
try test__fixint(f32, i1, -1.1, -1);
try test__fixint(f32, i1, -1.0, -1);
try test__fixint(f32, i1, -0.9, 0);
try test__fixint(f32, i1, -0.1, 0);
try test__fixint(f32, i1, -math.f32_min, 0);
try test__fixint(f32, i1, -math.floatMin(f32), 0);
try test__fixint(f32, i1, -0.0, 0);
try test__fixint(f32, i1, 0.0, 0);
try test__fixint(f32, i1, math.f32_min, 0);
try test__fixint(f32, i1, math.floatMin(f32), 0);
try test__fixint(f32, i1, 0.1, 0);
try test__fixint(f32, i1, 0.9, 0);
try test__fixint(f32, i1, 1.0, 0);
try test__fixint(f32, i1, 2.0, 0);
try test__fixint(f32, i1, math.f32_max, 0);
try test__fixint(f32, i1, math.inf_f32, 0);
try test__fixint(f32, i1, math.floatMax(f32), 0);
try test__fixint(f32, i1, math.inf(f32), 0);
}
test "fixint.i2" {
try test__fixint(f32, i2, -math.inf_f32, -2);
try test__fixint(f32, i2, -math.f32_max, -2);
try test__fixint(f32, i2, -math.inf(f32), -2);
try test__fixint(f32, i2, -math.floatMax(f32), -2);
try test__fixint(f32, i2, -2.0, -2);
try test__fixint(f32, i2, -1.9, -1);
try test__fixint(f32, i2, -1.1, -1);
try test__fixint(f32, i2, -1.0, -1);
try test__fixint(f32, i2, -0.9, 0);
try test__fixint(f32, i2, -0.1, 0);
try test__fixint(f32, i2, -math.f32_min, 0);
try test__fixint(f32, i2, -math.floatMin(f32), 0);
try test__fixint(f32, i2, -0.0, 0);
try test__fixint(f32, i2, 0.0, 0);
try test__fixint(f32, i2, math.f32_min, 0);
try test__fixint(f32, i2, math.floatMin(f32), 0);
try test__fixint(f32, i2, 0.1, 0);
try test__fixint(f32, i2, 0.9, 0);
try test__fixint(f32, i2, 1.0, 1);
try test__fixint(f32, i2, 2.0, 1);
try test__fixint(f32, i2, math.f32_max, 1);
try test__fixint(f32, i2, math.inf_f32, 1);
try test__fixint(f32, i2, math.floatMax(f32), 1);
try test__fixint(f32, i2, math.inf(f32), 1);
}
test "fixint.i3" {
try test__fixint(f32, i3, -math.inf_f32, -4);
try test__fixint(f32, i3, -math.f32_max, -4);
try test__fixint(f32, i3, -math.inf(f32), -4);
try test__fixint(f32, i3, -math.floatMax(f32), -4);
try test__fixint(f32, i3, -4.0, -4);
try test__fixint(f32, i3, -3.0, -3);
try test__fixint(f32, i3, -2.0, -2);
@ -62,23 +62,23 @@ test "fixint.i3" {
try test__fixint(f32, i3, -1.0, -1);
try test__fixint(f32, i3, -0.9, 0);
try test__fixint(f32, i3, -0.1, 0);
try test__fixint(f32, i3, -math.f32_min, 0);
try test__fixint(f32, i3, -math.floatMin(f32), 0);
try test__fixint(f32, i3, -0.0, 0);
try test__fixint(f32, i3, 0.0, 0);
try test__fixint(f32, i3, math.f32_min, 0);
try test__fixint(f32, i3, math.floatMin(f32), 0);
try test__fixint(f32, i3, 0.1, 0);
try test__fixint(f32, i3, 0.9, 0);
try test__fixint(f32, i3, 1.0, 1);
try test__fixint(f32, i3, 2.0, 2);
try test__fixint(f32, i3, 3.0, 3);
try test__fixint(f32, i3, 4.0, 3);
try test__fixint(f32, i3, math.f32_max, 3);
try test__fixint(f32, i3, math.inf_f32, 3);
try test__fixint(f32, i3, math.floatMax(f32), 3);
try test__fixint(f32, i3, math.inf(f32), 3);
}
test "fixint.i32" {
try test__fixint(f64, i32, -math.inf_f64, math.minInt(i32));
try test__fixint(f64, i32, -math.f64_max, math.minInt(i32));
try test__fixint(f64, i32, -math.inf(f64), math.minInt(i32));
try test__fixint(f64, i32, -math.floatMax(f64), math.minInt(i32));
try test__fixint(f64, i32, @as(f64, math.minInt(i32)), math.minInt(i32));
try test__fixint(f64, i32, @as(f64, math.minInt(i32)) + 1, math.minInt(i32) + 1);
try test__fixint(f64, i32, -2.0, -2);
@ -87,22 +87,22 @@ test "fixint.i32" {
try test__fixint(f64, i32, -1.0, -1);
try test__fixint(f64, i32, -0.9, 0);
try test__fixint(f64, i32, -0.1, 0);
try test__fixint(f64, i32, -math.f32_min, 0);
try test__fixint(f64, i32, -@as(f64, math.floatMin(f32)), 0);
try test__fixint(f64, i32, -0.0, 0);
try test__fixint(f64, i32, 0.0, 0);
try test__fixint(f64, i32, math.f32_min, 0);
try test__fixint(f64, i32, @as(f64, math.floatMin(f32)), 0);
try test__fixint(f64, i32, 0.1, 0);
try test__fixint(f64, i32, 0.9, 0);
try test__fixint(f64, i32, 1.0, 1);
try test__fixint(f64, i32, @as(f64, math.maxInt(i32)) - 1, math.maxInt(i32) - 1);
try test__fixint(f64, i32, @as(f64, math.maxInt(i32)), math.maxInt(i32));
try test__fixint(f64, i32, math.f64_max, math.maxInt(i32));
try test__fixint(f64, i32, math.inf_f64, math.maxInt(i32));
try test__fixint(f64, i32, math.floatMax(f64), math.maxInt(i32));
try test__fixint(f64, i32, math.inf(f64), math.maxInt(i32));
}
test "fixint.i64" {
try test__fixint(f64, i64, -math.inf_f64, math.minInt(i64));
try test__fixint(f64, i64, -math.f64_max, math.minInt(i64));
try test__fixint(f64, i64, -math.inf(f64), math.minInt(i64));
try test__fixint(f64, i64, -math.floatMax(f64), math.minInt(i64));
try test__fixint(f64, i64, @as(f64, math.minInt(i64)), math.minInt(i64));
try test__fixint(f64, i64, @as(f64, math.minInt(i64)) + 1, math.minInt(i64));
try test__fixint(f64, i64, @as(f64, math.minInt(i64) / 2), math.minInt(i64) / 2);
@ -112,22 +112,22 @@ test "fixint.i64" {
try test__fixint(f64, i64, -1.0, -1);
try test__fixint(f64, i64, -0.9, 0);
try test__fixint(f64, i64, -0.1, 0);
try test__fixint(f64, i64, -math.f32_min, 0);
try test__fixint(f64, i64, -@as(f64, math.floatMin(f32)), 0);
try test__fixint(f64, i64, -0.0, 0);
try test__fixint(f64, i64, 0.0, 0);
try test__fixint(f64, i64, math.f32_min, 0);
try test__fixint(f64, i64, @as(f64, math.floatMin(f32)), 0);
try test__fixint(f64, i64, 0.1, 0);
try test__fixint(f64, i64, 0.9, 0);
try test__fixint(f64, i64, 1.0, 1);
try test__fixint(f64, i64, @as(f64, math.maxInt(i64)) - 1, math.maxInt(i64));
try test__fixint(f64, i64, @as(f64, math.maxInt(i64)), math.maxInt(i64));
try test__fixint(f64, i64, math.f64_max, math.maxInt(i64));
try test__fixint(f64, i64, math.inf_f64, math.maxInt(i64));
try test__fixint(f64, i64, math.floatMax(f64), math.maxInt(i64));
try test__fixint(f64, i64, math.inf(f64), math.maxInt(i64));
}
test "fixint.i128" {
try test__fixint(f64, i128, -math.inf_f64, math.minInt(i128));
try test__fixint(f64, i128, -math.f64_max, math.minInt(i128));
try test__fixint(f64, i128, -math.inf(f64), math.minInt(i128));
try test__fixint(f64, i128, -math.floatMax(f64), math.minInt(i128));
try test__fixint(f64, i128, @as(f64, math.minInt(i128)), math.minInt(i128));
try test__fixint(f64, i128, @as(f64, math.minInt(i128)) + 1, math.minInt(i128));
try test__fixint(f64, i128, -2.0, -2);
@ -136,15 +136,15 @@ test "fixint.i128" {
try test__fixint(f64, i128, -1.0, -1);
try test__fixint(f64, i128, -0.9, 0);
try test__fixint(f64, i128, -0.1, 0);
try test__fixint(f64, i128, -math.f32_min, 0);
try test__fixint(f64, i128, -@as(f64, math.floatMin(f32)), 0);
try test__fixint(f64, i128, -0.0, 0);
try test__fixint(f64, i128, 0.0, 0);
try test__fixint(f64, i128, math.f32_min, 0);
try test__fixint(f64, i128, @as(f64, math.floatMin(f32)), 0);
try test__fixint(f64, i128, 0.1, 0);
try test__fixint(f64, i128, 0.9, 0);
try test__fixint(f64, i128, 1.0, 1);
try test__fixint(f64, i128, @as(f64, math.maxInt(i128)) - 1, math.maxInt(i128));
try test__fixint(f64, i128, @as(f64, math.maxInt(i128)), math.maxInt(i128));
try test__fixint(f64, i128, math.f64_max, math.maxInt(i128));
try test__fixint(f64, i128, math.inf_f64, math.maxInt(i128));
try test__fixint(f64, i128, math.floatMax(f64), math.maxInt(i128));
try test__fixint(f64, i128, math.inf(f64), math.maxInt(i128));
}

View File

@ -9,7 +9,7 @@ fn test__fixsfdi(a: f32, expected: i64) !void {
}
test "fixsfdi" {
try test__fixsfdi(-math.f32_max, math.minInt(i64));
try test__fixsfdi(-math.floatMax(f32), math.minInt(i64));
try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
@ -33,9 +33,9 @@ test "fixsfdi" {
try test__fixsfdi(-1.0, -1);
try test__fixsfdi(-0.99, 0);
try test__fixsfdi(-0.5, 0);
try test__fixsfdi(-math.f32_min, 0);
try test__fixsfdi(-math.floatMin(f32), 0);
try test__fixsfdi(0.0, 0);
try test__fixsfdi(math.f32_min, 0);
try test__fixsfdi(math.floatMin(f32), 0);
try test__fixsfdi(0.5, 0);
try test__fixsfdi(0.99, 0);
try test__fixsfdi(1.0, 1);
@ -60,5 +60,5 @@ test "fixsfdi" {
try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
try test__fixsfdi(math.f64_max, math.maxInt(i64));
try test__fixsfdi(math.floatMax(f32), math.maxInt(i64));
}

View File

@ -9,7 +9,7 @@ fn test__fixsfsi(a: f32, expected: i32) !void {
}
test "fixsfsi" {
try test__fixsfsi(-math.f32_max, math.minInt(i32));
try test__fixsfsi(-math.floatMax(f32), math.minInt(i32));
try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
@ -37,9 +37,9 @@ test "fixsfsi" {
try test__fixsfsi(-1.0, -1);
try test__fixsfsi(-0.99, 0);
try test__fixsfsi(-0.5, 0);
try test__fixsfsi(-math.f32_min, 0);
try test__fixsfsi(-math.floatMin(f32), 0);
try test__fixsfsi(0.0, 0);
try test__fixsfsi(math.f32_min, 0);
try test__fixsfsi(math.floatMin(f32), 0);
try test__fixsfsi(0.5, 0);
try test__fixsfsi(0.99, 0);
try test__fixsfsi(1.0, 1);
@ -68,5 +68,5 @@ test "fixsfsi" {
try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
try test__fixsfsi(math.f32_max, math.maxInt(i32));
try test__fixsfsi(math.floatMax(f32), math.maxInt(i32));
}

View File

@ -9,7 +9,7 @@ fn test__fixsfti(a: f32, expected: i128) !void {
}
test "fixsfti" {
try test__fixsfti(-math.f32_max, math.minInt(i128));
try test__fixsfti(-math.floatMax(f32), math.minInt(i128));
try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
@ -41,9 +41,9 @@ test "fixsfti" {
try test__fixsfti(-1.0, -1);
try test__fixsfti(-0.99, 0);
try test__fixsfti(-0.5, 0);
try test__fixsfti(-math.f32_min, 0);
try test__fixsfti(-math.floatMin(f32), 0);
try test__fixsfti(0.0, 0);
try test__fixsfti(math.f32_min, 0);
try test__fixsfti(math.floatMin(f32), 0);
try test__fixsfti(0.5, 0);
try test__fixsfti(0.99, 0);
try test__fixsfti(1.0, 1);
@ -76,5 +76,5 @@ test "fixsfti" {
try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
try test__fixsfti(math.f32_max, math.maxInt(i128));
try test__fixsfti(math.floatMax(f32), math.maxInt(i128));
}

View File

@ -9,7 +9,7 @@ fn test__fixtfdi(a: f128, expected: i64) !void {
}
test "fixtfdi" {
try test__fixtfdi(-math.f128_max, math.minInt(i64));
try test__fixtfdi(-math.floatMax(f128), math.minInt(i64));
try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
@ -37,9 +37,9 @@ test "fixtfdi" {
try test__fixtfdi(-1.0, -1);
try test__fixtfdi(-0.99, 0);
try test__fixtfdi(-0.5, 0);
try test__fixtfdi(-math.f64_min, 0);
try test__fixtfdi(-@as(f128, math.floatMin(f64)), 0);
try test__fixtfdi(0.0, 0);
try test__fixtfdi(math.f64_min, 0);
try test__fixtfdi(@as(f128, math.floatMin(f64)), 0);
try test__fixtfdi(0.5, 0);
try test__fixtfdi(0.99, 0);
try test__fixtfdi(1.0, 1);
@ -68,5 +68,5 @@ test "fixtfdi" {
try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
try test__fixtfdi(math.f128_max, math.maxInt(i64));
try test__fixtfdi(math.floatMax(f128), math.maxInt(i64));
}

View File

@ -9,7 +9,7 @@ fn test__fixtfsi(a: f128, expected: i32) !void {
}
test "fixtfsi" {
try test__fixtfsi(-math.f128_max, math.minInt(i32));
try test__fixtfsi(-math.floatMax(f128), math.minInt(i32));
try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
@ -37,9 +37,9 @@ test "fixtfsi" {
try test__fixtfsi(-1.0, -1);
try test__fixtfsi(-0.99, 0);
try test__fixtfsi(-0.5, 0);
try test__fixtfsi(-math.f32_min, 0);
try test__fixtfsi(-@as(f128, math.floatMin(f32)), 0);
try test__fixtfsi(0.0, 0);
try test__fixtfsi(math.f32_min, 0);
try test__fixtfsi(@as(f128, math.floatMin(f32)), 0);
try test__fixtfsi(0.5, 0);
try test__fixtfsi(0.99, 0);
try test__fixtfsi(1.0, 1);
@ -68,5 +68,5 @@ test "fixtfsi" {
try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
try test__fixtfsi(math.f128_max, math.maxInt(i32));
try test__fixtfsi(math.floatMax(f128), math.maxInt(i32));
}

View File

@ -9,7 +9,7 @@ fn test__fixtfti(a: f128, expected: i128) !void {
}
test "fixtfti" {
try test__fixtfti(-math.f128_max, math.minInt(i128));
try test__fixtfti(-math.floatMax(f128), math.minInt(i128));
try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
@ -32,9 +32,9 @@ test "fixtfti" {
try test__fixtfti(-1.0, -1);
try test__fixtfti(-0.99, 0);
try test__fixtfti(-0.5, 0);
try test__fixtfti(-math.f128_min, 0);
try test__fixtfti(-math.floatMin(f128), 0);
try test__fixtfti(0.0, 0);
try test__fixtfti(math.f128_min, 0);
try test__fixtfti(math.floatMin(f128), 0);
try test__fixtfti(0.5, 0);
try test__fixtfti(0.99, 0);
try test__fixtfti(1.0, 1);
@ -58,5 +58,5 @@ test "fixtfti" {
try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
try test__fixtfti(math.f128_max, math.maxInt(i128));
try test__fixtfti(math.floatMax(f128), math.maxInt(i128));
}

View File

@ -15,10 +15,10 @@ fn test_fmodl_nans() !void {
}
fn test_fmodl_infs() !void {
try testing.expect(fmodl.fmodl(1.0, std.math.inf_f128) == 1.0);
try testing.expect(fmodl.fmodl(1.0, -std.math.inf_f128) == 1.0);
try testing.expect(std.math.isNan(fmodl.fmodl(std.math.inf_f128, 1.0)));
try testing.expect(std.math.isNan(fmodl.fmodl(-std.math.inf_f128, 1.0)));
try testing.expect(fmodl.fmodl(1.0, std.math.inf(f128)) == 1.0);
try testing.expect(fmodl.fmodl(1.0, -std.math.inf(f128)) == 1.0);
try testing.expect(std.math.isNan(fmodl.fmodl(std.math.inf(f128), 1.0)));
try testing.expect(std.math.isNan(fmodl.fmodl(-std.math.inf(f128), 1.0)));
}
test "fmodl" {

View File

@ -641,7 +641,7 @@ test "vector reduce operation" {
// equal.
} else {
const F = @TypeOf(expected);
const tolerance = @sqrt(math.epsilon(TX));
const tolerance = @sqrt(math.floatEps(TX));
try expect(std.math.approxEqRel(F, expected, r, tolerance));
}
},