|
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 |
0c7d46 |
int f, i, j;
|
|
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 |
}
|