Blame src/math/lrint.c

nsz 0c7d46
#include "test.h"
nsz 0c7d46
#include <math.h>
nsz 0c7d46
#include <stdint.h>
nsz 0c7d46
#include <fenv.h>
nsz 0c7d46
#include <stdio.h>
nsz 0c7d46
#include <float.h>
nsz 0c7d46
nsz 0c7d46
static struct {
nsz 0c7d46
	int flag;
nsz 0c7d46
	char *s;
nsz 0c7d46
} eflags[] = {
nsz 0c7d46
	{FE_INVALID, "FE_INVALID"},
nsz 0c7d46
	{FE_DIVBYZERO, "FE_DIVBYZERO"},
nsz 0c7d46
	{FE_OVERFLOW, "FE_OVERFLOW"},
nsz 0c7d46
	{FE_UNDERFLOW, "FE_UNDERFLOW"},
nsz 0c7d46
	{FE_INEXACT, "FE_INEXACT"},
nsz 0c7d46
};
nsz 0c7d46
static int ne = sizeof eflags / sizeof *eflags;
nsz 0c7d46
nsz 0c7d46
static struct {
nsz 0c7d46
	int flag;
nsz 0c7d46
	char *s;
nsz 0c7d46
} rflags[] = {
nsz 0c7d46
	{FE_TONEAREST,"FE_TONEAREST,"},
nsz 0c7d46
	{FE_DOWNWARD,"FE_DOWNWARD,"},
nsz 0c7d46
	{FE_UPWARD,"FE_UPWARD,"},
nsz 0c7d46
	{FE_TOWARDZERO,"FE_TOWARDZERO,"},
nsz 0c7d46
};
nsz 0c7d46
static int nr = sizeof rflags / sizeof *rflags;
nsz 0c7d46
nsz 0c7d46
void printexcept(int f) {
nsz 0c7d46
	int i, all=0;
nsz 0c7d46
nsz 0c7d46
	for (i = 0; i < ne; i++)
nsz 0c7d46
		if (f & eflags[i].flag) {
nsz 0c7d46
			printf("%s%s", all ? "|" : "", eflags[i].s);
nsz 0c7d46
			all |= eflags[i].flag;
nsz 0c7d46
		}
nsz 0c7d46
	if (all != f) {
nsz 0c7d46
		printf("%s%d", all ? "|" : "", f & ~all);
nsz 0c7d46
		all = f;
nsz 0c7d46
	}
nsz 0c7d46
	printf("%s,", all ? "" : "0");
nsz 0c7d46
}
nsz 0c7d46
nsz 0c7d46
void printround(int f) {
nsz 0c7d46
	int i;
nsz 0c7d46
nsz 0c7d46
	for (i = 0; i < nr; i++)
nsz 0c7d46
		if (f == rflags[i].flag) {
nsz 0c7d46
			printf("%s ", rflags[i].s);
nsz 0c7d46
			return;
nsz 0c7d46
		}
nsz 0c7d46
	printf("%d, ", f);
nsz 0c7d46
}
nsz 0c7d46
nsz 0c7d46
/*
nsz 0c7d46
struct {double x;} t[] = {
nsz 0c7d46
0.0,
nsz 0c7d46
0.25,
nsz 0c7d46
-0.25,
nsz 0c7d46
0.5,
nsz 0c7d46
-0.5,
nsz 0c7d46
0.75,
nsz 0c7d46
-0.75,
nsz 0c7d46
1.0,
nsz 0c7d46
-1.0,
nsz 0c7d46
1.25,
nsz 0c7d46
-1.25,
nsz 0c7d46
0x1p30,
nsz 0c7d46
-0x1p30,
nsz 0c7d46
0x1p31-1,
nsz 0c7d46
-0x1p31+1,
nsz 0c7d46
0x1p31,
nsz 0c7d46
-0x1p31,
nsz 0c7d46
0x1p31+1,
nsz 0c7d46
-0x1p31-1,
nsz 0c7d46
0x1p31-0.5,
nsz 0c7d46
-0x1p31+0.5,
nsz 0c7d46
0x1p31+0.5,
nsz 0c7d46
-0x1p31-0.5,
nsz 0c7d46
0x1p32,
nsz 0c7d46
-0x1p32,
nsz 0c7d46
0x1p32 - 0.5,
nsz 0c7d46
-0x1p32 + 0.5,
nsz 0c7d46
};
nsz 0c7d46
nsz 0c7d46
void test_gendata()
nsz 0c7d46
{
nsz 0c7d46
	int f, i, j;
nsz 0c7d46
	long n;
nsz 0c7d46
nsz 0c7d46
	for (i = 0; i < sizeof t/sizeof *t; i++) {
nsz 0c7d46
		for (j = 0; j < nr; j++) {
nsz 0c7d46
			fesetround(rflags[j].flag);
nsz 0c7d46
			feclearexcept(FE_ALL_EXCEPT);
nsz 0c7d46
			n = lrint(t[i].x);
nsz 0c7d46
			f = fetestexcept(FE_ALL_EXCEPT);
nsz 0c7d46
			if (f == FE_INVALID)
nsz 0c7d46
				n = 0;
nsz 0c7d46
nsz 0c7d46
			printround(rflags[j].flag);
nsz 0c7d46
			printf("%18a, %11ld, ", t[i].x, n);
nsz 0c7d46
			printexcept(f);
nsz 0c7d46
			printf("\n");
nsz 0c7d46
		}
nsz 0c7d46
	}
nsz 0c7d46
}
nsz 0c7d46
*/
nsz 0c7d46
nsz 0c7d46
static struct {
nsz 0c7d46
	int round;
nsz 0c7d46
	double x;
nsz 0c7d46
	long n;
nsz 0c7d46
	int except;
nsz 0c7d46
} t[] = {
nsz 0c7d46
FE_TONEAREST,             0x0p+0,           0, 0,
nsz 0c7d46
FE_DOWNWARD,              0x0p+0,           0, 0,
nsz 0c7d46
FE_UPWARD,                0x0p+0,           0, 0,
nsz 0c7d46
FE_TOWARDZERO,            0x0p+0,           0, 0,
nsz 0c7d46
FE_TONEAREST,             0x1p-2,           0, FE_INEXACT,
nsz 0c7d46
FE_DOWNWARD,              0x1p-2,           0, FE_INEXACT,
nsz 0c7d46
FE_UPWARD,                0x1p-2,           1, FE_INEXACT,
nsz 0c7d46
FE_TOWARDZERO,            0x1p-2,           0, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,            -0x1p-2,           0, FE_INEXACT,
nsz 0c7d46
FE_DOWNWARD,             -0x1p-2,          -1, FE_INEXACT,
nsz 0c7d46
FE_UPWARD,               -0x1p-2,           0, FE_INEXACT,
nsz 0c7d46
FE_TOWARDZERO,           -0x1p-2,           0, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,             0x1p-1,           0, FE_INEXACT,
nsz 0c7d46
FE_DOWNWARD,              0x1p-1,           0, FE_INEXACT,
nsz 0c7d46
FE_UPWARD,                0x1p-1,           1, FE_INEXACT,
nsz 0c7d46
FE_TOWARDZERO,            0x1p-1,           0, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,            -0x1p-1,           0, FE_INEXACT,
nsz 0c7d46
FE_DOWNWARD,             -0x1p-1,          -1, FE_INEXACT,
nsz 0c7d46
FE_UPWARD,               -0x1p-1,           0, FE_INEXACT,
nsz 0c7d46
FE_TOWARDZERO,           -0x1p-1,           0, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,           0x1.8p-1,           1, FE_INEXACT,
nsz 0c7d46
FE_DOWNWARD,            0x1.8p-1,           0, FE_INEXACT,
nsz 0c7d46
FE_UPWARD,              0x1.8p-1,           1, FE_INEXACT,
nsz 0c7d46
FE_TOWARDZERO,          0x1.8p-1,           0, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,          -0x1.8p-1,          -1, FE_INEXACT,
nsz 0c7d46
FE_DOWNWARD,           -0x1.8p-1,          -1, FE_INEXACT,
nsz 0c7d46
FE_UPWARD,             -0x1.8p-1,           0, FE_INEXACT,
nsz 0c7d46
FE_TOWARDZERO,         -0x1.8p-1,           0, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,             0x1p+0,           1, 0,
nsz 0c7d46
FE_DOWNWARD,              0x1p+0,           1, 0,
nsz 0c7d46
FE_UPWARD,                0x1p+0,           1, 0,
nsz 0c7d46
FE_TOWARDZERO,            0x1p+0,           1, 0,
nsz 0c7d46
FE_TONEAREST,            -0x1p+0,          -1, 0,
nsz 0c7d46
FE_DOWNWARD,             -0x1p+0,          -1, 0,
nsz 0c7d46
FE_UPWARD,               -0x1p+0,          -1, 0,
nsz 0c7d46
FE_TOWARDZERO,           -0x1p+0,          -1, 0,
nsz 0c7d46
FE_TONEAREST,           0x1.4p+0,           1, FE_INEXACT,
nsz 0c7d46
FE_DOWNWARD,            0x1.4p+0,           1, FE_INEXACT,
nsz 0c7d46
FE_UPWARD,              0x1.4p+0,           2, FE_INEXACT,
nsz 0c7d46
FE_TOWARDZERO,          0x1.4p+0,           1, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,          -0x1.4p+0,          -1, FE_INEXACT,
nsz 0c7d46
FE_DOWNWARD,           -0x1.4p+0,          -2, FE_INEXACT,
nsz 0c7d46
FE_UPWARD,             -0x1.4p+0,          -1, FE_INEXACT,
nsz 0c7d46
FE_TOWARDZERO,         -0x1.4p+0,          -1, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,            0x1p+30,  1073741824, 0,
nsz 0c7d46
FE_DOWNWARD,             0x1p+30,  1073741824, 0,
nsz 0c7d46
FE_UPWARD,               0x1p+30,  1073741824, 0,
nsz 0c7d46
FE_TOWARDZERO,           0x1p+30,  1073741824, 0,
nsz 0c7d46
FE_TONEAREST,           -0x1p+30, -1073741824, 0,
nsz 0c7d46
FE_DOWNWARD,            -0x1p+30, -1073741824, 0,
nsz 0c7d46
FE_UPWARD,              -0x1p+30, -1073741824, 0,
nsz 0c7d46
FE_TOWARDZERO,          -0x1p+30, -1073741824, 0,
nsz 0c7d46
FE_TONEAREST,   0x1.fffffffcp+30,  2147483647, 0,
nsz 0c7d46
FE_DOWNWARD,    0x1.fffffffcp+30,  2147483647, 0,
nsz 0c7d46
FE_UPWARD,      0x1.fffffffcp+30,  2147483647, 0,
nsz 0c7d46
FE_TOWARDZERO,  0x1.fffffffcp+30,  2147483647, 0,
nsz 0c7d46
FE_TONEAREST,  -0x1.fffffffcp+30, -2147483647, 0,
nsz 0c7d46
FE_DOWNWARD,   -0x1.fffffffcp+30, -2147483647, 0,
nsz 0c7d46
FE_UPWARD,     -0x1.fffffffcp+30, -2147483647, 0,
nsz 0c7d46
FE_TOWARDZERO, -0x1.fffffffcp+30, -2147483647, 0,
nsz 0c7d46
FE_TONEAREST,            0x1p+31,           0, FE_INVALID,
nsz 0c7d46
FE_DOWNWARD,             0x1p+31,           0, FE_INVALID,
nsz 0c7d46
FE_UPWARD,               0x1p+31,           0, FE_INVALID,
nsz 0c7d46
FE_TOWARDZERO,           0x1p+31,           0, FE_INVALID,
nsz 0c7d46
FE_TONEAREST,           -0x1p+31, -2147483648, 0,
nsz 0c7d46
FE_DOWNWARD,            -0x1p+31, -2147483648, 0,
nsz 0c7d46
FE_UPWARD,              -0x1p+31, -2147483648, 0,
nsz 0c7d46
FE_TOWARDZERO,          -0x1p+31, -2147483648, 0,
nsz 0c7d46
FE_TONEAREST,   0x1.00000002p+31,           0, FE_INVALID,
nsz 0c7d46
FE_DOWNWARD,    0x1.00000002p+31,           0, FE_INVALID,
nsz 0c7d46
FE_UPWARD,      0x1.00000002p+31,           0, FE_INVALID,
nsz 0c7d46
FE_TOWARDZERO,  0x1.00000002p+31,           0, FE_INVALID,
nsz 0c7d46
FE_TONEAREST,  -0x1.00000002p+31,           0, FE_INVALID,
nsz 0c7d46
FE_DOWNWARD,   -0x1.00000002p+31,           0, FE_INVALID,
nsz 0c7d46
FE_UPWARD,     -0x1.00000002p+31,           0, FE_INVALID,
nsz 0c7d46
FE_TOWARDZERO, -0x1.00000002p+31,           0, FE_INVALID,
nsz 0c7d46
FE_TONEAREST,   0x1.fffffffep+30,           0, FE_INVALID,
nsz 0c7d46
FE_DOWNWARD,    0x1.fffffffep+30,  2147483647, FE_INEXACT,
nsz 0c7d46
FE_UPWARD,      0x1.fffffffep+30,           0, FE_INVALID,
nsz 0c7d46
FE_TOWARDZERO,  0x1.fffffffep+30,  2147483647, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,  -0x1.fffffffep+30, -2147483648, FE_INEXACT,
nsz 0c7d46
FE_DOWNWARD,   -0x1.fffffffep+30, -2147483648, FE_INEXACT,
nsz 0c7d46
FE_UPWARD,     -0x1.fffffffep+30, -2147483647, FE_INEXACT,
nsz 0c7d46
FE_TOWARDZERO, -0x1.fffffffep+30, -2147483647, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,   0x1.00000001p+31,           0, FE_INVALID,
nsz 0c7d46
FE_DOWNWARD,    0x1.00000001p+31,           0, FE_INVALID,
nsz 0c7d46
FE_UPWARD,      0x1.00000001p+31,           0, FE_INVALID,
nsz 0c7d46
FE_TOWARDZERO,  0x1.00000001p+31,           0, FE_INVALID,
nsz 0c7d46
FE_TONEAREST,  -0x1.00000001p+31, -2147483648, FE_INEXACT,
nsz 0c7d46
FE_DOWNWARD,   -0x1.00000001p+31,           0, FE_INVALID,
nsz 0c7d46
FE_UPWARD,     -0x1.00000001p+31, -2147483648, FE_INEXACT,
nsz 0c7d46
FE_TOWARDZERO, -0x1.00000001p+31, -2147483648, FE_INEXACT,
nsz 0c7d46
FE_TONEAREST,            0x1p+32,           0, FE_INVALID,
nsz 0c7d46
FE_DOWNWARD,             0x1p+32,           0, FE_INVALID,
nsz 0c7d46
FE_UPWARD,               0x1p+32,           0, FE_INVALID,
nsz 0c7d46
FE_TOWARDZERO,           0x1p+32,           0, FE_INVALID,
nsz 0c7d46
FE_TONEAREST,           -0x1p+32,           0, FE_INVALID,
nsz 0c7d46
FE_DOWNWARD,            -0x1p+32,           0, FE_INVALID,
nsz 0c7d46
FE_UPWARD,              -0x1p+32,           0, FE_INVALID,
nsz 0c7d46
FE_TOWARDZERO,          -0x1p+32,           0, FE_INVALID,
nsz 0c7d46
FE_TONEAREST,   0x1.ffffffffp+31,           0, FE_INVALID,
nsz 0c7d46
FE_DOWNWARD,    0x1.ffffffffp+31,           0, FE_INVALID,
nsz 0c7d46
FE_UPWARD,      0x1.ffffffffp+31,           0, FE_INVALID,
nsz 0c7d46
FE_TOWARDZERO,  0x1.ffffffffp+31,           0, FE_INVALID,
nsz 0c7d46
FE_TONEAREST,  -0x1.ffffffffp+31,           0, FE_INVALID,
nsz 0c7d46
FE_DOWNWARD,   -0x1.ffffffffp+31,           0, FE_INVALID,
nsz 0c7d46
FE_UPWARD,     -0x1.ffffffffp+31,           0, FE_INVALID,
nsz 0c7d46
FE_TOWARDZERO, -0x1.ffffffffp+31,           0, FE_INVALID,
nsz 0c7d46
};
nsz 0c7d46
nsz 0c7d46
void test_lrint()
nsz 0c7d46
{
nsz a9d0a0
	int f, i;
nsz 0c7d46
	long n;
nsz 0c7d46
nsz 0c7d46
	for (i = 0; i < sizeof t/sizeof *t; i++) {
nsz 0c7d46
		fesetround(t[i].round);
nsz 0c7d46
		feclearexcept(FE_ALL_EXCEPT);
nsz 0c7d46
		n = lrint(t[i].x);
nsz 0c7d46
		f = fetestexcept(FE_ALL_EXCEPT);
nsz 0c7d46
nsz 0c7d46
		if (t[i].except != FE_INVALID && n != t[i].n) {
nsz 0c7d46
			error("round=");
nsz 0c7d46
			printround(t[i].round);
nsz 0c7d46
			printf("lrint(%a) want %ld got %ld\n", t[i].x, t[i].n, n);
nsz 0c7d46
		}
nsz 0c7d46
		if (f != t[i].except) {
nsz 0c7d46
			error("round=");
nsz 0c7d46
			printround(t[i].round);
nsz 0c7d46
			printf("lrint(%a)==%ld want except=", t[i].x, t[i].n);
nsz 0c7d46
			printexcept(t[i].except);
nsz 0c7d46
			printf(" got except=");
nsz 0c7d46
			printexcept(f);
nsz 0c7d46
			printf("\n");
nsz 0c7d46
		}
nsz 0c7d46
	}
nsz 0c7d46
}
nsz 0c7d46
nsz 0c7d46
void bench_lrint_simple(int N)
nsz 0c7d46
{
nsz 0c7d46
	int i;
nsz 0c7d46
	volatile int n;
nsz 0c7d46
nsz 0c7d46
	for (i = 0; i < N; i++) {
nsz 0c7d46
		n = lrint(1.25);
nsz 0c7d46
	}
nsz 0c7d46
}
nsz 0c7d46
nsz 0c7d46
void bench_lrint_hard(int N)
nsz 0c7d46
{
nsz 0c7d46
	int i;
nsz 0c7d46
	volatile int n;
nsz 0c7d46
nsz 0c7d46
	for (i = 0; i < N; i++) {
nsz 0c7d46
//		feclearexcept(FE_ALL_EXCEPT);
nsz 0c7d46
//		n = lrint(1.5);
nsz 0c7d46
//		n = lrint(0x1p32);
nsz 0c7d46
//		n = lrint(-0x1p31);
nsz 0c7d46
		n = lrint(0x1p31+0.5);
nsz 0c7d46
	}
nsz 0c7d46
}