Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/softfloat/generic/comparison.c

    r750636a rc67aff2  
    11/*
    22 * Copyright (c) 2005 Josef Cejka
     3 * Copyright (c) 2011 Petr Koupy
    34 * All rights reserved.
    45 *
     
    3031 * @{
    3132 */
    32 /** @file
     33/** @file Comparison functions.
    3334 */
    3435
    3536#include <sftypes.h>
    3637#include <comparison.h>
    37 
    38 /* NaN : exp = 0xff and nonzero fraction */
     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 */
    3947int isFloat32NaN(float32 f)
    4048{
     49        /* NaN : exp = 0xff and nonzero fraction */
    4150        return ((f.parts.exp == 0xFF) && (f.parts.fraction));
    4251}
    4352
    44 /* NaN : exp = 0x7ff and nonzero fraction */
     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 */
    4560int isFloat64NaN(float64 d)
    4661{
     62        /* NaN : exp = 0x7ff and nonzero fraction */
    4763        return ((d.parts.exp == 0x7FF) && (d.parts.fraction));
    4864}
    4965
    50 /* SigNaN : exp = 0xff fraction = 0xxxxx..x (binary), where at least one x is nonzero */
     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 */
    5186int isFloat32SigNaN(float32 f)
    5287{
    53         return ((f.parts.exp == 0xFF) && (f.parts.fraction < 0x400000) && (f.parts.fraction));
    54 }
    55 
    56 /* SigNaN : exp = 0x7ff fraction = 0xxxxx..x (binary), where at least one x is nonzero */
     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 */
    57100int isFloat64SigNaN(float64 d)
    58101{
    59         return ((d.parts.exp == 0x7FF) && (d.parts.fraction) && (d.parts.fraction < 0x8000000000000ll));
    60 }
    61 
     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 */
    62130int isFloat32Infinity(float32 f)
    63131{
     132        /* NaN : exp = 0x7ff and zero fraction */
    64133        return ((f.parts.exp == 0xFF) && (f.parts.fraction == 0x0));
    65134}
    66135
     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 */
    67142int isFloat64Infinity(float64 d)
    68143{
     144        /* NaN : exp = 0x7ff and zero fraction */
    69145        return ((d.parts.exp == 0x7FF) && (d.parts.fraction == 0x0));
    70146}
    71147
     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 */
    72167int isFloat32Zero(float32 f)
    73168{
     
    75170}
    76171
     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 */
    77178int isFloat64Zero(float64 d)
    78179{
     
    81182
    82183/**
    83  * @return 1 if both floats are equal - but NaNs are not recognized
     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.
    84206 */
    85207int isFloat32eq(float32 a, float32 b)
    86208{
    87209        /* a equals to b or both are zeros (with any sign) */
    88         return ((a.binary==b.binary) || (((a.binary | b.binary) & 0x7FFFFFFF) == 0));
    89 }
    90 
    91 /**
    92  * @return 1 if a < b - but NaNs are not recognized
     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.
    93259 */
    94260int isFloat32lt(float32 a, float32 b)
    95261{
    96         if (((a.binary | b.binary) & 0x7FFFFFFF) == 0)
     262        if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) {
    97263                return 0; /* +- zeroes */
     264        }
    98265       
    99         if ((a.parts.sign) && (b.parts.sign))
     266        if ((a.parts.sign) && (b.parts.sign)) {
    100267                /* if both are negative, smaller is that with greater binary value */
    101268                return (a.binary > b.binary);
     269        }
    102270       
    103         /* lets negate signs - now will be positive numbers allways bigger than negative (first bit will be set for unsigned integer comparison) */
     271        /* lets negate signs - now will be positive numbers allways bigger than
     272         * negative (first bit will be set for unsigned integer comparison) */
    104273        a.parts.sign = !a.parts.sign;
    105274        b.parts.sign = !b.parts.sign;
     
    108277
    109278/**
    110  * @return 1 if a > b - but NaNs are not recognized
     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.
    111341 */
    112342int isFloat32gt(float32 a, float32 b)
    113343{
    114         if (((a.binary | b.binary) & 0x7FFFFFFF) == 0)
     344        if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) {
    115345                return 0; /* zeroes are equal with any sign */
     346        }
    116347       
    117         if ((a.parts.sign) && (b.parts.sign))
     348        if ((a.parts.sign) && (b.parts.sign)) {
    118349                /* if both are negative, greater is that with smaller binary value */
    119350                return (a.binary < b.binary);
     351        }
    120352       
    121         /* lets negate signs - now will be positive numbers allways bigger than negative (first bit will be set for unsigned integer comparison) */
     353        /* lets negate signs - now will be positive numbers allways bigger than
     354         *  negative (first bit will be set for unsigned integer comparison) */
    122355        a.parts.sign = !a.parts.sign;
    123356        b.parts.sign = !b.parts.sign;
     
    125358}
    126359
     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
    127417/** @}
    128418 */
Note: See TracChangeset for help on using the changeset viewer.