/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2024 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ │ above copyright notice and this permission notice appear in all copies. │ │ │ │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/math.h" #define CHECK(x) \ if (!(x)) \ return __LINE__ #define FALSE(x) \ { \ volatile bool x_ = x; \ if (x_) \ return __LINE__; \ } #define TRUE(x) \ { \ volatile bool x_ = x; \ if (!x_) \ return __LINE__; \ } _Float16 identity(_Float16 x) { return x; } _Float16 (*half)(_Float16) = identity; int main() { volatile float f; volatile double d; volatile _Float16 pi = 3.141; // half → float → half f = pi; pi = f; // half → float float __extendhfsf2(_Float16); CHECK(0.f == __extendhfsf2(0)); CHECK(3.140625f == __extendhfsf2(pi)); CHECK(3.140625f == pi); // half → double → half d = pi; pi = d; // half → double double __extendhfdf2(_Float16); CHECK(0. == __extendhfdf2(0)); CHECK(3.140625 == __extendhfdf2(pi)); // float → half _Float16 __truncsfhf2(float); CHECK(0 == (float)__truncsfhf2(0)); CHECK(pi == (float)__truncsfhf2(3.141f)); CHECK(3.140625f == (float)__truncsfhf2(3.141f)); // double → half _Float16 __truncdfhf2(double); CHECK(0 == (double)__truncdfhf2(0)); CHECK(3.140625 == (double)__truncdfhf2(3.141)); // specials volatile _Float16 nan = NAN; volatile _Float16 positive_infinity = +INFINITY; volatile _Float16 negative_infinity = -INFINITY; CHECK(isnan(nan)); CHECK(!isinf(pi)); CHECK(!isnan(pi)); CHECK(isinf(positive_infinity)); CHECK(isinf(negative_infinity)); CHECK(!isnan(positive_infinity)); CHECK(!isnan(negative_infinity)); CHECK(!signbit(pi)); CHECK(signbit(half(-pi))); CHECK(!signbit(half(+0.))); CHECK(signbit(half(-0.))); // arithmetic CHECK(half(-3) == -half(3)); CHECK(half(9) == half(3) * half(3)); CHECK(half(0) == half(pi) - half(pi)); CHECK(half(6.28125) == half(pi) + half(pi)); // comparisons CHECK(half(3) > half(2)); CHECK(half(3) < half(4)); CHECK(half(3) <= half(3)); CHECK(half(3) >= half(3)); TRUE(half(NAN) != half(NAN)); FALSE(half(NAN) == half(NAN)); TRUE(half(3) != half(NAN)); FALSE(half(3) == half(NAN)); TRUE(half(NAN) != half(3)); FALSE(half(NAN) == half(3)); }