Path: blob/main/lib/libc/tests/gen/fpsetround_test.c
289379 views
/* $NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $ */12/*-3* Copyright (c) 2011 The NetBSD Foundation, Inc.4* All rights reserved.5*6* This code is derived from software contributed to The NetBSD Foundation7* by Christos Zoulas.8*9* Redistribution and use in source and binary forms, with or without10* modification, are permitted provided that the following conditions11* are met:12* 1. Redistributions of source code must retain the above copyright13* notice, this list of conditions and the following disclaimer.14* 2. Redistributions in binary form must reproduce the above copyright15* notice, this list of conditions and the following disclaimer in the16* documentation and/or other materials provided with the distribution.17* 3. All advertising materials mentioning features or use of this software18* must display the following acknowledgement:19* This product includes software developed by the NetBSD20* Foundation, Inc. and its contributors.21* 4. Neither the name of The NetBSD Foundation nor the names of its22* contributors may be used to endorse or promote products derived23* from this software without specific prior written permission.24*25* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS26* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED27* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR28* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS29* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR30* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF31* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS32* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN33* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)34* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE35* POSSIBILITY OF SUCH DAMAGE.36*/37#include <sys/cdefs.h>38__RCSID("$NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $");3940#include <float.h>41#include <math.h>42#include <stdlib.h>43#include <string.h>44#include <stdio.h>4546#include <atf-c.h>4748ATF_TC(fpsetround_basic);49ATF_TC_HEAD(fpsetround_basic, tc)50{5152atf_tc_set_md_var(tc, "descr",53"Minimal testing of fpgetround(3) and fpsetround(3)");54}5556#ifdef __i386__57#include <ieeefp.h>58#define __arraycount(a) (sizeof(a) / sizeof(*(a)))5960static const struct {61const char *n;62int rm;63int rf;64} rnd[] = {65{ "RN", FP_RN, 1 },66{ "RP", FP_RP, 2 },67{ "RM", FP_RM, 3 },68{ "RZ", FP_RZ, 0 },6970};7172static const struct {73const char *n;74int v[4];75} tst[] = { /* RN RP RM RZ */76{ "1.1", { 1, 1, 2, 1 } },77{ "1.5", { 1, 2, 2, 1 } },78{ "1.9", { 1, 2, 2, 1 } },79{ "2.1", { 2, 2, 3, 2 } },80{ "2.5", { 2, 2, 3, 2 } },81{ "2.9", { 2, 3, 3, 2 } },82{ "-1.1", { -1, -1, -1, -2 } },83{ "-1.5", { -1, -2, -1, -2 } },84{ "-1.9", { -1, -2, -1, -2 } },85{ "-2.1", { -2, -2, -2, -3 } },86{ "-2.5", { -2, -2, -2, -3 } },87{ "-2.9", { -2, -3, -2, -3 } },88};8990static const char *91getname(int r)92{93for (size_t i = 0; i < __arraycount(rnd); i++)94if (rnd[i].rm == r)95return rnd[i].n;96return "*unknown*";97}9899static void100test(int r)101{102int did = 0;103for (size_t i = 0; i < __arraycount(tst); i++) {104double d = strtod(tst[i].n, NULL);105int g = (int)rint(d);106int e = tst[i].v[r];107ATF_CHECK_EQ(g, e);108if (g != e) {109if (!did) {110fprintf(stderr, "Mode Value Result Expected\n");111did = 1;112}113fprintf(stderr, "%4.4s %-5.5s %6d %8d\n", rnd[r].n,114tst[i].n, (int)rint(d), tst[i].v[r]);115}116}117}118#endif119120121ATF_TC_BODY(fpsetround_basic, tc)122{123124#ifndef __i386__125atf_tc_skip("Test not applicable on this architecture.");126#else127int r;128129ATF_CHECK_EQ(r = fpgetround(), FP_RN);130if (FP_RN != r)131fprintf(stderr, "default expected=%s got=%s\n", getname(FP_RN),132getname(r));133ATF_CHECK_EQ(FLT_ROUNDS, 1);134135for (size_t i = 0; i < __arraycount(rnd); i++) {136const size_t j = (i + 1) & 3;137const int o = rnd[i].rm;138const int n = rnd[j].rm;139140ATF_CHECK_EQ(r = fpsetround(n), o);141if (o != r)142fprintf(stderr, "set %s expected=%s got=%s\n",143getname(n), getname(o), getname(r));144ATF_CHECK_EQ(r = fpgetround(), n);145if (n != r)146fprintf(stderr, "get expected=%s got=%s\n", getname(n),147getname(r));148ATF_CHECK_EQ(r = FLT_ROUNDS, rnd[j].rf);149if (r != rnd[j].rf)150fprintf(stderr, "rounds expected=%x got=%x\n",151rnd[j].rf, r);152test(r);153}154#endif /* __i386__ */155}156157ATF_TP_ADD_TCS(tp)158{159160ATF_TP_ADD_TC(tp, fpsetround_basic);161162return atf_no_error();163}164165166