source: mainline/uspace/lib/softfloat/generic/comparison.c@ 9d58539

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9d58539 was 9d58539, checked in by Prutkov Alex <prutkov.alex@…>, 13 years ago

Fixed unix permissions for all files

  • Property mode set to 100644
File size: 12.0 KB
Line 
1/*
2 * Copyright (c) 2005 Josef Cejka
3 * Copyright (c) 2011 Petr Koupy
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/** @addtogroup softfloat
31 * @{
32 */
33/** @file Comparison functions.
34 */
35
36#include <sftypes.h>
37#include <comparison.h>
38#include <common.h>
39
40/**
41 * Determines whether the given float represents NaN (either signalling NaN or
42 * quiet NaN).
43 *
44 * @param f Single-precision float.
45 * @return 1 if float is NaN, 0 otherwise.
46 */
47int isFloat32NaN(float32 f)
48{
49 /* NaN : exp = 0xff and nonzero fraction */
50 return ((f.parts.exp == 0xFF) && (f.parts.fraction));
51}
52
53/**
54 * Determines whether the given float represents NaN (either signalling NaN or
55 * quiet NaN).
56 *
57 * @param d Double-precision float.
58 * @return 1 if float is NaN, 0 otherwise.
59 */
60int isFloat64NaN(float64 d)
61{
62 /* NaN : exp = 0x7ff and nonzero fraction */
63 return ((d.parts.exp == 0x7FF) && (d.parts.fraction));
64}
65
66/**
67 * Determines whether the given float represents NaN (either signalling NaN or
68 * quiet NaN).
69 *
70 * @param ld Quadruple-precision float.
71 * @return 1 if float is NaN, 0 otherwise.
72 */
73int isFloat128NaN(float128 ld)
74{
75 /* NaN : exp = 0x7fff and nonzero fraction */
76 return ((ld.parts.exp == 0x7FF) &&
77 !eq128(ld.parts.frac_hi, ld.parts.frac_lo, 0x0ll, 0x0ll));
78}
79
80/**
81 * Determines whether the given float represents signalling NaN.
82 *
83 * @param f Single-precision float.
84 * @return 1 if float is signalling NaN, 0 otherwise.
85 */
86int isFloat32SigNaN(float32 f)
87{
88 /* SigNaN : exp = 0xff and fraction = 0xxxxx..x (binary),
89 * where at least one x is nonzero */
90 return ((f.parts.exp == 0xFF) &&
91 (f.parts.fraction < 0x400000) && (f.parts.fraction));
92}
93
94/**
95 * Determines whether the given float represents signalling NaN.
96 *
97 * @param d Double-precision float.
98 * @return 1 if float is signalling NaN, 0 otherwise.
99 */
100int isFloat64SigNaN(float64 d)
101{
102 /* SigNaN : exp = 0x7ff and fraction = 0xxxxx..x (binary),
103 * where at least one x is nonzero */
104 return ((d.parts.exp == 0x7FF) &&
105 (d.parts.fraction) && (d.parts.fraction < 0x8000000000000ll));
106}
107
108/**
109 * Determines whether the given float represents signalling NaN.
110 *
111 * @param ld Quadruple-precision float.
112 * @return 1 if float is signalling NaN, 0 otherwise.
113 */
114int isFloat128SigNaN(float128 ld)
115{
116 /* SigNaN : exp = 0x7fff and fraction = 0xxxxx..x (binary),
117 * where at least one x is nonzero */
118 return ((ld.parts.exp == 0x7FFF) &&
119 (ld.parts.frac_hi || ld.parts.frac_lo) &&
120 lt128(ld.parts.frac_hi, ld.parts.frac_lo, 0x800000000000ll, 0x0ll));
121
122}
123
124/**
125 * Determines whether the given float represents positive or negative infinity.
126 *
127 * @param f Single-precision float.
128 * @return 1 if float is infinite, 0 otherwise.
129 */
130int isFloat32Infinity(float32 f)
131{
132 /* NaN : exp = 0x7ff and zero fraction */
133 return ((f.parts.exp == 0xFF) && (f.parts.fraction == 0x0));
134}
135
136/**
137 * Determines whether the given float represents positive or negative infinity.
138 *
139 * @param d Double-precision float.
140 * @return 1 if float is infinite, 0 otherwise.
141 */
142int isFloat64Infinity(float64 d)
143{
144 /* NaN : exp = 0x7ff and zero fraction */
145 return ((d.parts.exp == 0x7FF) && (d.parts.fraction == 0x0));
146}
147
148/**
149 * Determines whether the given float represents positive or negative infinity.
150 *
151 * @param ld Quadruple-precision float.
152 * @return 1 if float is infinite, 0 otherwise.
153 */
154int isFloat128Infinity(float128 ld)
155{
156 /* NaN : exp = 0x7fff and zero fraction */
157 return ((ld.parts.exp == 0x7FFF) &&
158 eq128(ld.parts.frac_hi, ld.parts.frac_lo, 0x0ll, 0x0ll));
159}
160
161/**
162 * Determines whether the given float represents positive or negative zero.
163 *
164 * @param f Single-precision float.
165 * @return 1 if float is zero, 0 otherwise.
166 */
167int isFloat32Zero(float32 f)
168{
169 return (((f.binary) & 0x7FFFFFFF) == 0);
170}
171
172/**
173 * Determines whether the given float represents positive or negative zero.
174 *
175 * @param d Double-precision float.
176 * @return 1 if float is zero, 0 otherwise.
177 */
178int isFloat64Zero(float64 d)
179{
180 return (((d.binary) & 0x7FFFFFFFFFFFFFFFll) == 0);
181}
182
183/**
184 * Determines whether the given float represents positive or negative zero.
185 *
186 * @param ld Quadruple-precision float.
187 * @return 1 if float is zero, 0 otherwise.
188 */
189int isFloat128Zero(float128 ld)
190{
191 uint64_t tmp_hi;
192 uint64_t tmp_lo;
193
194 and128(ld.binary.hi, ld.binary.lo,
195 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
196
197 return eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll);
198}
199
200/**
201 * Determine whether two floats are equal. NaNs are not recognized.
202 *
203 * @a First single-precision operand.
204 * @b Second single-precision operand.
205 * @return 1 if both floats are equal, 0 otherwise.
206 */
207int isFloat32eq(float32 a, float32 b)
208{
209 /* a equals to b or both are zeros (with any sign) */
210 return ((a.binary == b.binary) ||
211 (((a.binary | b.binary) & 0x7FFFFFFF) == 0));
212}
213
214/**
215 * Determine whether two floats are equal. NaNs are not recognized.
216 *
217 * @a First double-precision operand.
218 * @b Second double-precision operand.
219 * @return 1 if both floats are equal, 0 otherwise.
220 */
221int isFloat64eq(float64 a, float64 b)
222{
223 /* a equals to b or both are zeros (with any sign) */
224 return ((a.binary == b.binary) ||
225 (((a.binary | b.binary) & 0x7FFFFFFFFFFFFFFFll) == 0));
226}
227
228/**
229 * Determine whether two floats are equal. NaNs are not recognized.
230 *
231 * @a First quadruple-precision operand.
232 * @b Second quadruple-precision operand.
233 * @return 1 if both floats are equal, 0 otherwise.
234 */
235int isFloat128eq(float128 a, float128 b)
236{
237 uint64_t tmp_hi;
238 uint64_t tmp_lo;
239
240 /* both are zeros (with any sign) */
241 or128(a.binary.hi, a.binary.lo,
242 b.binary.hi, b.binary.lo, &tmp_hi, &tmp_lo);
243 and128(tmp_hi, tmp_lo,
244 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
245 int both_zero = eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll);
246
247 /* a equals to b */
248 int are_equal = eq128(a.binary.hi, a.binary.lo, b.binary.hi, b.binary.lo);
249
250 return are_equal || both_zero;
251}
252
253/**
254 * Lower-than comparison between two floats. NaNs are not recognized.
255 *
256 * @a First single-precision operand.
257 * @b Second single-precision operand.
258 * @return 1 if a is lower than b, 0 otherwise.
259 */
260int isFloat32lt(float32 a, float32 b)
261{
262 if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) {
263 return 0; /* +- zeroes */
264 }
265
266 if ((a.parts.sign) && (b.parts.sign)) {
267 /* if both are negative, smaller is that with greater binary value */
268 return (a.binary > b.binary);
269 }
270
271 /* lets negate signs - now will be positive numbers allways bigger than
272 * negative (first bit will be set for unsigned integer comparison) */
273 a.parts.sign = !a.parts.sign;
274 b.parts.sign = !b.parts.sign;
275 return (a.binary < b.binary);
276}
277
278/**
279 * Lower-than comparison between two floats. NaNs are not recognized.
280 *
281 * @a First double-precision operand.
282 * @b Second double-precision operand.
283 * @return 1 if a is lower than b, 0 otherwise.
284 */
285int isFloat64lt(float64 a, float64 b)
286{
287 if (((a.binary | b.binary) & 0x7FFFFFFFFFFFFFFFll) == 0) {
288 return 0; /* +- zeroes */
289 }
290
291 if ((a.parts.sign) && (b.parts.sign)) {
292 /* if both are negative, smaller is that with greater binary value */
293 return (a.binary > b.binary);
294 }
295
296 /* lets negate signs - now will be positive numbers allways bigger than
297 * negative (first bit will be set for unsigned integer comparison) */
298 a.parts.sign = !a.parts.sign;
299 b.parts.sign = !b.parts.sign;
300 return (a.binary < b.binary);
301}
302
303/**
304 * Lower-than comparison between two floats. NaNs are not recognized.
305 *
306 * @a First quadruple-precision operand.
307 * @b Second quadruple-precision operand.
308 * @return 1 if a is lower than b, 0 otherwise.
309 */
310int isFloat128lt(float128 a, float128 b)
311{
312 uint64_t tmp_hi;
313 uint64_t tmp_lo;
314
315 or128(a.binary.hi, a.binary.lo,
316 b.binary.hi, b.binary.lo, &tmp_hi, &tmp_lo);
317 and128(tmp_hi, tmp_lo,
318 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
319 if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
320 return 0; /* +- zeroes */
321 }
322
323 if ((a.parts.sign) && (b.parts.sign)) {
324 /* if both are negative, smaller is that with greater binary value */
325 return lt128(b.binary.hi, b.binary.lo, a.binary.hi, a.binary.lo);
326 }
327
328 /* lets negate signs - now will be positive numbers allways bigger than
329 * negative (first bit will be set for unsigned integer comparison) */
330 a.parts.sign = !a.parts.sign;
331 b.parts.sign = !b.parts.sign;
332 return lt128(a.binary.hi, a.binary.lo, b.binary.hi, b.binary.lo);
333}
334
335/**
336 * Greater-than comparison between two floats. NaNs are not recognized.
337 *
338 * @a First single-precision operand.
339 * @b Second single-precision operand.
340 * @return 1 if a is greater than b, 0 otherwise.
341 */
342int isFloat32gt(float32 a, float32 b)
343{
344 if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) {
345 return 0; /* zeroes are equal with any sign */
346 }
347
348 if ((a.parts.sign) && (b.parts.sign)) {
349 /* if both are negative, greater is that with smaller binary value */
350 return (a.binary < b.binary);
351 }
352
353 /* lets negate signs - now will be positive numbers allways bigger than
354 * negative (first bit will be set for unsigned integer comparison) */
355 a.parts.sign = !a.parts.sign;
356 b.parts.sign = !b.parts.sign;
357 return (a.binary > b.binary);
358}
359
360/**
361 * Greater-than comparison between two floats. NaNs are not recognized.
362 *
363 * @a First double-precision operand.
364 * @b Second double-precision operand.
365 * @return 1 if a is greater than b, 0 otherwise.
366 */
367int isFloat64gt(float64 a, float64 b)
368{
369 if (((a.binary | b.binary) & 0x7FFFFFFFFFFFFFFFll) == 0) {
370 return 0; /* zeroes are equal with any sign */
371 }
372
373 if ((a.parts.sign) && (b.parts.sign)) {
374 /* if both are negative, greater is that with smaller binary value */
375 return (a.binary < b.binary);
376 }
377
378 /* lets negate signs - now will be positive numbers allways bigger than
379 * negative (first bit will be set for unsigned integer comparison) */
380 a.parts.sign = !a.parts.sign;
381 b.parts.sign = !b.parts.sign;
382 return (a.binary > b.binary);
383}
384
385/**
386 * Greater-than comparison between two floats. NaNs are not recognized.
387 *
388 * @a First quadruple-precision operand.
389 * @b Second quadruple-precision operand.
390 * @return 1 if a is greater than b, 0 otherwise.
391 */
392int isFloat128gt(float128 a, float128 b)
393{
394 uint64_t tmp_hi;
395 uint64_t tmp_lo;
396
397 or128(a.binary.hi, a.binary.lo,
398 b.binary.hi, b.binary.lo, &tmp_hi, &tmp_lo);
399 and128(tmp_hi, tmp_lo,
400 0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
401 if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
402 return 0; /* zeroes are equal with any sign */
403 }
404
405 if ((a.parts.sign) && (b.parts.sign)) {
406 /* if both are negative, greater is that with smaller binary value */
407 return lt128(a.binary.hi, a.binary.lo, b.binary.hi, b.binary.lo);
408 }
409
410 /* lets negate signs - now will be positive numbers allways bigger than
411 * negative (first bit will be set for unsigned integer comparison) */
412 a.parts.sign = !a.parts.sign;
413 b.parts.sign = !b.parts.sign;
414 return lt128(b.binary.hi, b.binary.lo, a.binary.hi, a.binary.lo);
415}
416
417/** @}
418 */
Note: See TracBrowser for help on using the repository browser.