source: mainline/uspace/app/tester/float/float2.c

Last change on this file was 516e780, checked in by GitHub <noreply@…>, 7 years ago

Strip down libmath. (#45)

libmath is mostly unused (except for trunc(), sin() and cos()), and most functions in it are either very imprecise or downright broken. Additionally, it is implemented in manner that conflicts with C standard. Instead of trying to fix all the shortcomings while maintaining unused functionality, I'm opting to simply remove most of it and only keep the parts that are currently necessary.

Later readdition of the removed functions is possible, but there needs to be a reliable way to evaluate their quality first.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright (c) 2014 Martin Decky
3 * Copyright (c) 2015 Jiri Svoboda
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <stdbool.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <stddef.h>
34#include <math.h>
35#include "../tester.h"
36
37#define OPERANDS 10
38#define PRECISIONF 10000
39#define PRECISION 100000000
40
41static double arguments[OPERANDS] = {
42 3.5, -2.1, 100.0, 50.0, -1024.0, 0.0, 768.3156, 1080.499999, -600.0, 1.0
43};
44
45static double results_cos[OPERANDS] = {
46 -0.936456687291, -0.504846104600, 0.862318872288, 0.964966028492,
47 0.987353618220, 1.0, -0.194939922623, 0.978471923925, -0.999023478833,
48 0.540302305868
49};
50
51static double results_sin[OPERANDS] = {
52 -0.350783227690, -0.863209366649, -0.506365641110, -0.262374853704,
53 0.158533380044, 0.0, 0.980815184715, -0.206379975025, -0.044182448332,
54 0.841470984808
55};
56
57static double results_trunc[OPERANDS] = {
58 3.0, -2.0, 100.0, 50.0, -1024.0, 0.0, 768.0, 1080.0, -600.0, 1.0
59};
60
61static bool cmp_float(float a, float b)
62{
63 float r;
64
65 /* XXX Need fabsf() */
66 if (b < 1.0 / PRECISIONF && b > -1.0 / PRECISIONF)
67 r = a;
68 else
69 r = a / b - 1.0;
70
71 /* XXX Need fabsf() */
72 if (r < 0.0)
73 r = -r;
74
75 return r < 1.0 / PRECISIONF;
76}
77
78static bool cmp_double(double a, double b)
79{
80 double r;
81
82 /* XXX Need fabs() */
83 if (b < 1.0 / PRECISION && b > -1.0 / PRECISION)
84 r = a;
85 else
86 r = a / b - 1.0;
87
88 /* XXX Need fabs() */
89 if (r < 0.0)
90 r = -r;
91
92 return r < 1.0 / PRECISION;
93}
94
95const char *test_float2(void)
96{
97 bool fail = false;
98
99 for (unsigned int i = 0; i < OPERANDS; i++) {
100 double res = cos(arguments[i]);
101
102 if (!cmp_double(res, results_cos[i])) {
103 TPRINTF("Double precision cos failed "
104 "(%lf != %lf, arg %u)\n", res, results_cos[i], i);
105 fail = true;
106 }
107 }
108
109 for (unsigned int i = 0; i < OPERANDS; i++) {
110 float res = cosf(arguments[i]);
111
112 if (!cmp_float(res, results_cos[i])) {
113 TPRINTF("Single precision cos failed "
114 "(%f != %lf, arg %u)\n", res, results_cos[i], i);
115 fail = true;
116 }
117 }
118
119 for (unsigned int i = 0; i < OPERANDS; i++) {
120 double res = sin(arguments[i]);
121
122 if (!cmp_double(res, results_sin[i])) {
123 TPRINTF("Double precision sin failed "
124 "(%lf != %lf, arg %u)\n", res, results_sin[i], i);
125 fail = true;
126 }
127 }
128
129 for (unsigned int i = 0; i < OPERANDS; i++) {
130 float res = sinf(arguments[i]);
131
132 if (!cmp_float(res, results_sin[i])) {
133 TPRINTF("Single precision sin failed "
134 "(%f != %lf, arg %u)\n", res, results_sin[i], i);
135 fail = true;
136 }
137 }
138
139 for (unsigned int i = 0; i < OPERANDS; i++) {
140 double res = trunc(arguments[i]);
141
142 if (!cmp_double(res, results_trunc[i])) {
143 TPRINTF("Double precision trunc failed "
144 "(%lf != %lf, arg %u)\n", res, results_trunc[i], i);
145 fail = true;
146 }
147 }
148
149 for (unsigned int i = 0; i < OPERANDS; i++) {
150 float res = truncf(arguments[i]);
151
152 if (!cmp_float(res, results_trunc[i])) {
153 TPRINTF("Single precision trunc failed "
154 "(%f != %lf, arg %u)\n", res, results_trunc[i], i);
155 fail = true;
156 }
157 }
158
159 if (fail)
160 return "Floating point imprecision";
161
162 return NULL;
163}
Note: See TracBrowser for help on using the repository browser.