brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.4 KiB · 1787b83 Raw
378 lines · c
1// RUN: %clang_builtins %s -ffp-contract=off %librt -lm -o %t && %run %t2// REQUIRES: librt_has_muldc33// REQUIRES: c99-complex4 5#include "int_lib.h"6#include <math.h>7#include <complex.h>8#include <stdio.h>9 10#define RELATIVE_TOLERANCE 1e-911 12// Returns: the product of a + ib and c + id13 14COMPILER_RT_ABI double _Complex15__muldc3(double __a, double __b, double __c, double __d);16 17enum {zero, non_zero, inf, NaN, non_zero_nan};18 19int check_complex_equal(double _Complex r1, double _Complex r2)20{21    double max_magnitude = fmax(cabs(r1), cabs(r2));22    double real_diff = fabs(creal(r1) - creal(r2));23    double imag_diff = fabs(cimag(r1) - cimag(r2));24    if (real_diff >= max_magnitude * RELATIVE_TOLERANCE)25      return 0;26    if (imag_diff >= max_magnitude * RELATIVE_TOLERANCE)27      return 0;28 29    return 1;30}31 32int33classify(double _Complex x)34{35    if (x == 0)36        return zero;37    if (isinf(creal(x)) || isinf(cimag(x)))38        return inf;39    if (isnan(creal(x)) && isnan(cimag(x)))40        return NaN;41    if (isnan(creal(x)))42    {43        if (cimag(x) == 0)44            return NaN;45        return non_zero_nan;46    }47    if (isnan(cimag(x)))48    {49        if (creal(x) == 0)50            return NaN;51        return non_zero_nan;52    }53    return non_zero;54}55 56int test__muldc3(double a, double b, double c, double d)57{58    double _Complex r = __muldc3(a, b, c, d);59//     printf("test__muldc3(%f, %f, %f, %f) = %f + I%f\n",60//             a, b, c, d, creal(r), cimag(r));61	double _Complex dividend;62	double _Complex divisor;63  double _Complex temp;	64 65	__real__ dividend = a;66	__imag__ dividend = b;67	__real__ divisor = c;68	__imag__ divisor = d;69 70  __real__ temp = a * c - b * d;71  __imag__ temp = a * d + b * c;72	73    switch (classify(dividend))74    {75    case zero:76        switch (classify(divisor))77        {78        case zero:79            if (classify(r) != zero)80                return 1;81            break;82        case non_zero:83            if (classify(r) != zero)84                return 1;85            break;86        case inf:87            if (classify(r) != NaN)88                return 1;89            break;90        case NaN:91            if (classify(r) != NaN)92                return 1;93            break;94        case non_zero_nan:95            if (classify(r) != NaN)96                return 1;97            break;98        }99        break;100    case non_zero:101        switch (classify(divisor))102        {103        case zero:104            if (classify(r) != zero)105                return 1;106            break;107        case non_zero:108            if (classify(r) != non_zero)109                return 1;110            if (!check_complex_equal(r, temp))111                return 1;112            break;113        case inf:114            if (classify(r) != inf)115                return 1;116            break;117        case NaN:118            if (classify(r) != NaN)119                return 1;120            break;121        case non_zero_nan:122            if (classify(r) != NaN)123                return 1;124            break;125        }126        break;127    case inf:128        switch (classify(divisor))129        {130        case zero:131            if (classify(r) != NaN)132                return 1;133            break;134        case non_zero:135            if (classify(r) != inf)136                return 1;137            break;138        case inf:139            if (classify(r) != inf)140                return 1;141            break;142        case NaN:143            if (classify(r) != NaN)144                return 1;145            break;146        case non_zero_nan:147            if (classify(r) != inf)148                return 1;149            break;150        }151        break;152    case NaN:153        switch (classify(divisor))154        {155        case zero:156            if (classify(r) != NaN)157                return 1;158            break;159        case non_zero:160            if (classify(r) != NaN)161                return 1;162            break;163        case inf:164            if (classify(r) != NaN)165                return 1;166            break;167        case NaN:168            if (classify(r) != NaN)169                return 1;170            break;171        case non_zero_nan:172            if (classify(r) != NaN)173                return 1;174            break;175        }176        break;177    case non_zero_nan:178        switch (classify(divisor))179        {180        case zero:181            if (classify(r) != NaN)182                return 1;183            break;184        case non_zero:185            if (classify(r) != NaN)186                return 1;187            break;188        case inf:189            if (classify(r) != inf)190                return 1;191            break;192        case NaN:193            if (classify(r) != NaN)194                return 1;195            break;196        case non_zero_nan:197            if (classify(r) != NaN)198                return 1;199            break;200        }201        break;202    }203    204    return 0;205}206 207double x[][2] =208{209    { 1.e-6,  1.e-6},210    {-1.e-6,  1.e-6},211    {-1.e-6, -1.e-6},212    { 1.e-6, -1.e-6},213 214    { 1.e+6,  1.e-6},215    {-1.e+6,  1.e-6},216    {-1.e+6, -1.e-6},217    { 1.e+6, -1.e-6},218 219    { 1.e-6,  1.e+6},220    {-1.e-6,  1.e+6},221    {-1.e-6, -1.e+6},222    { 1.e-6, -1.e+6},223 224    { 1.e+6,  1.e+6},225    {-1.e+6,  1.e+6},226    {-1.e+6, -1.e+6},227    { 1.e+6, -1.e+6},228 229    {NAN, NAN},230    {-INFINITY, NAN},231    {-2, NAN},232    {-1, NAN},233    {-0.5, NAN},234    {-0., NAN},235    {+0., NAN},236    {0.5, NAN},237    {1, NAN},238    {2, NAN},239    {INFINITY, NAN},240 241    {NAN, -INFINITY},242    {-INFINITY, -INFINITY},243    {-2, -INFINITY},244    {-1, -INFINITY},245    {-0.5, -INFINITY},246    {-0., -INFINITY},247    {+0., -INFINITY},248    {0.5, -INFINITY},249    {1, -INFINITY},250    {2, -INFINITY},251    {INFINITY, -INFINITY},252 253    {NAN, -2},254    {-INFINITY, -2},255    {-2, -2},256    {-1, -2},257    {-0.5, -2},258    {-0., -2},259    {+0., -2},260    {0.5, -2},261    {1, -2},262    {2, -2},263    {INFINITY, -2},264 265    {NAN, -1},266    {-INFINITY, -1},267    {-2, -1},268    {-1, -1},269    {-0.5, -1},270    {-0., -1},271    {+0., -1},272    {0.5, -1},273    {1, -1},274    {2, -1},275    {INFINITY, -1},276 277    {NAN, -0.5},278    {-INFINITY, -0.5},279    {-2, -0.5},280    {-1, -0.5},281    {-0.5, -0.5},282    {-0., -0.5},283    {+0., -0.5},284    {0.5, -0.5},285    {1, -0.5},286    {2, -0.5},287    {INFINITY, -0.5},288 289    {NAN, -0.},290    {-INFINITY, -0.},291    {-2, -0.},292    {-1, -0.},293    {-0.5, -0.},294    {-0., -0.},295    {+0., -0.},296    {0.5, -0.},297    {1, -0.},298    {2, -0.},299    {INFINITY, -0.},300 301    {NAN, 0.},302    {-INFINITY, 0.},303    {-2, 0.},304    {-1, 0.},305    {-0.5, 0.},306    {-0., 0.},307    {+0., 0.},308    {0.5, 0.},309    {1, 0.},310    {2, 0.},311    {INFINITY, 0.},312 313    {NAN, 0.5},314    {-INFINITY, 0.5},315    {-2, 0.5},316    {-1, 0.5},317    {-0.5, 0.5},318    {-0., 0.5},319    {+0., 0.5},320    {0.5, 0.5},321    {1, 0.5},322    {2, 0.5},323    {INFINITY, 0.5},324 325    {NAN, 1},326    {-INFINITY, 1},327    {-2, 1},328    {-1, 1},329    {-0.5, 1},330    {-0., 1},331    {+0., 1},332    {0.5, 1},333    {1, 1},334    {2, 1},335    {INFINITY, 1},336 337    {NAN, 2},338    {-INFINITY, 2},339    {-2, 2},340    {-1, 2},341    {-0.5, 2},342    {-0., 2},343    {+0., 2},344    {0.5, 2},345    {1, 2},346    {2, 2},347    {INFINITY, 2},348 349    {NAN, INFINITY},350    {-INFINITY, INFINITY},351    {-2, INFINITY},352    {-1, INFINITY},353    {-0.5, INFINITY},354    {-0., INFINITY},355    {+0., INFINITY},356    {0.5, INFINITY},357    {1, INFINITY},358    {2, INFINITY},359    {INFINITY, INFINITY}360 361};362 363int main()364{365    const unsigned N = sizeof(x) / sizeof(x[0]);366    unsigned i, j;367    for (i = 0; i < N; ++i)368    {369        for (j = 0; j < N; ++j)370        {371            if (test__muldc3(x[i][0], x[i][1], x[j][0], x[j][1]))372                return 1;373        }374    }375 376    return 0;377}378