zig/lib/std/math/isnan.zig
Alex Rønne Petersen c9e67e71c1
std.Target: Replace isARM() with isArmOrThumb() and rename it to isArm().
The old isARM() function was a portability trap. With the name it had, it seemed
like the obviously correct function to use, but it didn't include Thumb. In the
vast majority of cases where someone wants to ask "is the target Arm?", Thumb
*should* be included.

There are exactly 3 cases in the codebase where we do actually need to exclude
Thumb, although one of those is in Aro and mirrors a check in Clang that is
itself likely a bug. These rare cases can just add an extra isThumb() check.
2024-11-03 09:29:30 +01:00

46 lines
1.6 KiB
Zig

const std = @import("../std.zig");
const builtin = @import("builtin");
const math = std.math;
const meta = std.meta;
const expect = std.testing.expect;
pub fn isNan(x: anytype) bool {
return x != x;
}
/// TODO: LLVM is known to miscompile on some architectures to quiet NaN -
/// this is tracked by https://github.com/ziglang/zig/issues/14366
pub fn isSignalNan(x: anytype) bool {
const T = @TypeOf(x);
const U = meta.Int(.unsigned, @bitSizeOf(T));
const quiet_signal_bit_mask = 1 << (math.floatFractionalBits(T) - 1);
return isNan(x) and (@as(U, @bitCast(x)) & quiet_signal_bit_mask == 0);
}
test isNan {
inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
try expect(isNan(math.nan(T)));
try expect(isNan(-math.nan(T)));
try expect(isNan(math.snan(T)));
try expect(!isNan(@as(T, 1.0)));
try expect(!isNan(@as(T, math.inf(T))));
}
}
test isSignalNan {
inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
// TODO: Signalling NaN values get converted to quiet NaN values in
// some cases where they shouldn't such that this can fail.
// See https://github.com/ziglang/zig/issues/14366
if (!builtin.cpu.arch.isArm() and
!builtin.cpu.arch.isAARCH64() and
!builtin.cpu.arch.isPowerPC() and
builtin.zig_backend != .stage2_c)
{
try expect(isSignalNan(math.snan(T)));
}
try expect(!isSignalNan(math.nan(T)));
try expect(!isSignalNan(@as(T, 1.0)));
try expect(!isSignalNan(math.inf(T)));
}
}