1/*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#include <stdio.h>
25#include <stdbool.h>
26#include <string.h>
27#include <math.h>
28
29#include "macros.h"
30#include "rounding.h"
31
32int main(int argc, char *argv[])
33{
34   const struct {
35      float input, expected;
36   } float_data[] = {
37      { 0.0,                  0.0 },
38      { nextafterf(0.5, 0.0), 0.0 },
39      { 0.5,                  0.0 },
40      { nextafterf(0.5, 1.0), 1.0 },
41      { 1.0,                  1.0 },
42      { nextafterf(1.5, 1.0), 1.0 },
43      { 1.5,                  2.0 },
44      { nextafterf(1.5, 2.0), 2.0 },
45      { 2.0,                  2.0 },
46      { nextafterf(2.5, 2.0), 2.0 },
47      { 2.5,                  2.0 },
48      { nextafterf(2.5, 3.0), 3.0 },
49   };
50
51   const struct {
52      double input, expected;
53   } double_data[] = {
54      { 0.0,                 0.0 },
55      { nextafter(0.5, 0.0), 0.0 },
56      { 0.5,                 0.0 },
57      { nextafter(0.5, 1.0), 1.0 },
58      { 1.0,                 1.0 },
59      { nextafter(1.5, 1.0), 1.0 },
60      { 1.5,                 2.0 },
61      { nextafter(1.5, 2.0), 2.0 },
62      { 2.0,                 2.0 },
63      { nextafter(2.5, 2.0), 2.0 },
64      { 2.5,                 2.0 },
65      { nextafter(2.5, 3.0), 3.0 },
66   };
67
68   bool failed = false;
69   int i;
70
71   for (i = 0; i < ARRAY_SIZE(float_data); i++) {
72      float output = _mesa_roundevenf(float_data[i].input);
73      if (memcmp(&float_data[i].expected, &output, sizeof(float))) {
74         fprintf(stderr, "%d float: expected %f (%a) from "
75                         "_mesa_roundevenf(%f (%a)) but got %f (%a)\n",
76                 i,
77                 float_data[i].expected,
78                 float_data[i].expected,
79                 float_data[i].input,
80                 float_data[i].input,
81                 output,
82                 output);
83         failed = true;
84      }
85   }
86
87   /* Test negated values */
88   for (i = 0; i < ARRAY_SIZE(float_data); i++) {
89      float output = _mesa_roundevenf(-float_data[i].input);
90      float negated_expected = -float_data[i].expected;
91      if (memcmp(&negated_expected, &output, sizeof(float))) {
92         fprintf(stderr, "%d float: expected %f (%a) from "
93                         "_mesa_roundevenf(%f (%a)) but got %f (%a)\n",
94                 i,
95                 negated_expected,
96                 negated_expected,
97                 -float_data[i].input,
98                 -float_data[i].input,
99                 output,
100                 output);
101         failed = true;
102      }
103   }
104
105   for (i = 0; i < ARRAY_SIZE(double_data); i++) {
106      double output = _mesa_roundeven(double_data[i].input);
107      if (memcmp(&double_data[i].expected, &output, sizeof(double))) {
108         fprintf(stderr, "%d double: expected %f (%a) from "
109                         "_mesa_roundeven(%f (%a)) but got %f (%a)\n",
110                 i,
111                 double_data[i].expected,
112                 double_data[i].expected,
113                 double_data[i].input,
114                 double_data[i].input,
115                 output,
116                 output);
117         failed = true;
118      }
119   }
120
121   /* Test negated values */
122   for (i = 0; i < ARRAY_SIZE(double_data); i++) {
123      double output = _mesa_roundeven(-double_data[i].input);
124      double negated_expected = -double_data[i].expected;
125      if (memcmp(&negated_expected, &output, sizeof(double))) {
126         fprintf(stderr, "%d double: expected %f (%a) from "
127                         "_mesa_roundeven(%f (%a)) but got %f (%a)\n",
128                 i,
129                 negated_expected,
130                 negated_expected,
131                 -double_data[i].input,
132                 -double_data[i].input,
133                 output,
134                 output);
135         failed = true;
136      }
137   }
138
139   return failed;
140}
141