/* * The Rin Library – library "conformance" tests * * Copyright (C) 2015-2017 Gediminas Jakutis * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2.1 * of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include "test.h" #include "rin/float.h" static int signbitf_test(void); static int signbitd_test(void); static int float_to_hexstring_test(void); static int double_to_hexstring_test(void); static int compare_float_test(void); static int compare_double_test(void); int float_test(char *testname) { static const struct test tests[] = { {"signbitf", signbitf_test}, {"signbitd", signbitd_test}, {"floattohexstring", float_to_hexstring_test}, {"doubletohexstring", double_to_hexstring_test}, {"comparefloat", compare_float_test}, {"comparedouble", compare_double_test} }; size_t i; for (i = 0; i < arrlen(tests); ++i) { if (!strcmp(testname, tests[i].name)) { return tests[i].testfunc(); } } return EXIT_FAILURE; } static int signbitf_test(void) { int ret; size_t i; static const float in[] = { 1.0f, -1.0f, 987656.4321f, -987656.4321f }; static const uint32_t expected[] = { 0, 0x80000000u, 0, 0x80000000u }; for (i = 0; i < 4; ++i) { ret = ok(rin_signbitf(in[i]) != expected[i], "%s: expected: %"PRIu32", got: %"PRIu32" (%1.8e)", __func__, expected[i], rin_signbitf(in[i]), in[i]); } return ret; } static int signbitd_test(void) { int ret; size_t i; static const double in[] = { 1.0, -1.0, 987656.4321, -987656.4321 }; static const uint64_t expected[] = { 0, 0x8000000000000000ull, 0, 0x8000000000000000ull }; for (i = 0; i < 4; ++i) { ret = ok(rin_signbitd(in[i]) != expected[i], "%s: expected: %"PRIu64", got: %"PRIu64" (%1.16e)", __func__, expected[i], rin_signbitf(in[i]), in[i]); } return ret; } static int float_to_hexstring_test(void) { int ret; size_t i; static const float in[] = { 1.0f, -1.0f, 98765.4321f, -98765.4321f }; static const char *expected_default[] = { "0x3f800000", "0xbf800000", "0x47c0e6b7", "0xc7c0e6b7" }; static const char *expected_noprefix[] = { "3f800000", "bf800000", "47c0e6b7", "c7c0e6b7" }; char buffer[16] = { '\0' }; for (i = 0; i < 4; ++i) { ret = ok(strcmp(rin_float_to_hexstring(in[i], buffer, RIN_HEXSTRING_DEFAULT), expected_default[i]), "%s: expected: %s, got: %s (%1.8e)", __func__, expected_default[i], rin_float_to_hexstring(in[i], buffer, RIN_HEXSTRING_DEFAULT), in[i]); ret = ok(strcmp(rin_float_to_hexstring(in[i], buffer, RIN_HEXSTRING_NOPREFIX), expected_noprefix[i]), "%s: expected: %s, got: %s (%1.8e)", __func__, expected_noprefix[i], rin_float_to_hexstring(in[i], buffer, RIN_HEXSTRING_NOPREFIX), in[i]); } return ret; } static int double_to_hexstring_test(void) { int ret; size_t i; static const double in[] = { 1.0, -1.0, 98765.4321, -98765.4321 }; static const char *expected_default[] = { "0x3ff0000000000000", "0xbff0000000000000", "0x40f81cd6e9e1b08a", "0xc0f81cd6e9e1b08a" }; static const char *expected_noprefix[] = { "3ff0000000000000", "bff0000000000000", "40f81cd6e9e1b08a", "c0f81cd6e9e1b08a" }; char buffer[32] = { '\0' }; for (i = 0; i < 4; ++i) { ret = ok(strcmp(rin_double_to_hexstring(in[i], buffer, RIN_HEXSTRING_DEFAULT), expected_default[i]), "%s: expected: %s, got: %s (%1.16e)", __func__, expected_default[i], rin_double_to_hexstring(in[i], buffer, RIN_HEXSTRING_DEFAULT), in[i]); ret = ok(strcmp(rin_double_to_hexstring(in[i], buffer, RIN_HEXSTRING_NOPREFIX), expected_noprefix[i]), "%s: expected: %s, got: %s (%1.16e)", __func__, expected_noprefix[i], rin_double_to_hexstring(in[i], buffer, RIN_HEXSTRING_NOPREFIX), in[i]); } return ret; } static int compare_float_test(void) { int ret; size_t i; static const float a[] = { 0.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 98765.4321f, 98765.4321f, 98765.4321f }; static const float b[] = { -0.0f, 1.0f, 1.0f, 1.0000001f, -9.8f, 1.000001f, 98765.436f, 98777.7777f, -98765.4321f }; static const unsigned int expected[] = { 0, 0, 1, 0, 1, 1, 0, 1, 1}; for (i = 0; i < 4; ++i) { ret = ok(rin_compare_float(a[i], b[i], 2) != expected[i], "%s: expected: %s, got: %s (%1.8e, %1.8e)", __func__, expected[i] ? "non-equal" : "equal", rin_compare_float(a[i], b[i], 2) ? "non-equal" : "equal", a[i], b[i]); } return ret; } static int compare_double_test(void) { int ret; size_t i; static const double a[] = { 0.0, 1.0, -1.0, 1.0, -1.0f, 1.0, 98765.4321, 98765.4321, 98765.4321 }; static const double b[] = { -0.0, 1.0, 1.0, 1.0000000000000003, -9.8f, 1.000001, 98765.43210000002, 98777.7777, -98765.4321 }; static const unsigned int expected[] = { 0, 0, 1, 0, 1, 1, 0, 1, 1}; for (i = 0; i < 4; ++i) { ret = ok(rin_compare_double(a[i], b[i], 2) != expected[i], "%s: expected: %s, got: %s (%1.16e, %1.16e)", __func__, expected[i] ? "non-equal" : "equal", rin_compare_double(a[i], b[i], 2) ? "non-equal" : "equal", a[i], b[i]); } return ret; }