Ignore:
File:
1 edited

Legend:

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

    rc67aff2 r750636a  
    11/*
    22 * Copyright (c) 2005 Josef Cejka
    3  * Copyright (c) 2011 Petr Koupy
    43 * All rights reserved.
    54 *
     
    3130 * @{
    3231 */
    33 /** @file Comparison functions.
     32/** @file
    3433 */
    3534
    3635#include <sftypes.h>
    3736#include <comparison.h>
    38 #include <common.h>
    3937
    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  */
     38/* NaN : exp = 0xff and nonzero fraction */
    4739int isFloat32NaN(float32 f)
    4840{
    49         /* NaN : exp = 0xff and nonzero fraction */
    5041        return ((f.parts.exp == 0xFF) && (f.parts.fraction));
    5142}
    5243
    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  */
     44/* NaN : exp = 0x7ff and nonzero fraction */
    6045int isFloat64NaN(float64 d)
    6146{
    62         /* NaN : exp = 0x7ff and nonzero fraction */
    6347        return ((d.parts.exp == 0x7FF) && (d.parts.fraction));
    6448}
    6549
    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  */
    73 int isFloat128NaN(float128 ld)
     50/* SigNaN : exp = 0xff fraction = 0xxxxx..x (binary), where at least one x is nonzero */
     51int isFloat32SigNaN(float32 f)
    7452{
    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));
     53        return ((f.parts.exp == 0xFF) && (f.parts.fraction < 0x400000) && (f.parts.fraction));
    7854}
    7955
    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  */
    86 int isFloat32SigNaN(float32 f)
     56/* SigNaN : exp = 0x7ff fraction = 0xxxxx..x (binary), where at least one x is nonzero */
     57int isFloat64SigNaN(float64 d)
    8758{
    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));
     59        return ((d.parts.exp == 0x7FF) && (d.parts.fraction) && (d.parts.fraction < 0x8000000000000ll));
    9260}
    9361
    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  */
    100 int 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  */
    114 int 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  */
    13062int isFloat32Infinity(float32 f)
    13163{
    132         /* NaN : exp = 0x7ff and zero fraction */
    13364        return ((f.parts.exp == 0xFF) && (f.parts.fraction == 0x0));
    13465}
    13566
    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  */
    14267int isFloat64Infinity(float64 d)
    14368{
    144         /* NaN : exp = 0x7ff and zero fraction */
    14569        return ((d.parts.exp == 0x7FF) && (d.parts.fraction == 0x0));
    14670}
    14771
    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  */
    154 int 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  */
    16772int isFloat32Zero(float32 f)
    16873{
     
    17075}
    17176
    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  */
    17877int isFloat64Zero(float64 d)
    17978{
     
    18281
    18382/**
    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  */
    189 int 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.
     83 * @return 1 if both floats are equal - but NaNs are not recognized
    20684 */
    20785int isFloat32eq(float32 a, float32 b)
    20886{
    20987        /* a equals to b or both are zeros (with any sign) */
    210         return ((a.binary == b.binary) ||
    211             (((a.binary | b.binary) & 0x7FFFFFFF) == 0));
     88        return ((a.binary==b.binary) || (((a.binary | b.binary) & 0x7FFFFFFF) == 0));
    21289}
    21390
    21491/**
    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  */
    221 int 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  */
    235 int 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.
     92 * @return 1 if a < b - but NaNs are not recognized
    25993 */
    26094int isFloat32lt(float32 a, float32 b)
    26195{
    262         if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) {
     96        if (((a.binary | b.binary) & 0x7FFFFFFF) == 0)
    26397                return 0; /* +- zeroes */
    264         }
    26598       
    266         if ((a.parts.sign) && (b.parts.sign)) {
     99        if ((a.parts.sign) && (b.parts.sign))
    267100                /* if both are negative, smaller is that with greater binary value */
    268101                return (a.binary > b.binary);
    269         }
    270102       
    271         /* lets negate signs - now will be positive numbers allways bigger than
    272          * negative (first bit will be set for unsigned integer comparison) */
     103        /* lets negate signs - now will be positive numbers allways bigger than negative (first bit will be set for unsigned integer comparison) */
    273104        a.parts.sign = !a.parts.sign;
    274105        b.parts.sign = !b.parts.sign;
     
    277108
    278109/**
    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  */
    285 int 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  */
    310 int 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.
     110 * @return 1 if a > b - but NaNs are not recognized
    341111 */
    342112int isFloat32gt(float32 a, float32 b)
    343113{
    344         if (((a.binary | b.binary) & 0x7FFFFFFF) == 0) {
     114        if (((a.binary | b.binary) & 0x7FFFFFFF) == 0)
    345115                return 0; /* zeroes are equal with any sign */
    346         }
    347116       
    348         if ((a.parts.sign) && (b.parts.sign)) {
     117        if ((a.parts.sign) && (b.parts.sign))
    349118                /* if both are negative, greater is that with smaller binary value */
    350119                return (a.binary < b.binary);
    351         }
    352120       
    353         /* lets negate signs - now will be positive numbers allways bigger than
    354          *  negative (first bit will be set for unsigned integer comparison) */
     121        /* lets negate signs - now will be positive numbers allways bigger than negative (first bit will be set for unsigned integer comparison) */
    355122        a.parts.sign = !a.parts.sign;
    356123        b.parts.sign = !b.parts.sign;
     
    358125}
    359126
    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  */
    367 int 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  */
    392 int 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 
    417127/** @}
    418128 */
Note: See TracChangeset for help on using the changeset viewer.