summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gdc.test/runnable/nan.d
blob: d4e4ae4ebdc22ee2e90ff79dc78a9f1c844f69dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import core.stdc.stdio;

enum real er1 = real.nan;
enum real er2 = 1;
static assert(er1 != er2);
static assert(!(er1 == er2));
static assert(!(er1 < er2));
static assert(!(er1 > er2));
static assert(!(er1 >= er2));
static assert(!(er1 <= er2));

enum double ed1 = real.nan;
enum double ed2 = 1;
static assert(ed1 != ed2);
static assert(!(ed1 == ed2));
static assert(!(ed1 < ed2));
static assert(!(ed1 > ed2));
static assert(!(ed1 >= ed2));
static assert(!(ed1 <= ed2));

bool b;


T byCTFE(T)()
{
    T x;
    return x;
}

bool bittst(const ubyte[] ba, uint pos)
{
    uint mask = 1 << (pos % 8);
    version(LittleEndian)
        return (ba[pos / 8] & mask) != 0;
    else
        return (ba[$ - 1 - pos / 8] & mask) != 0;
}

void test2(T)()
{
    T a = T.init, b = T.nan;
    assert(a is b);

    enum c = byCTFE!T();
    assert(a is c);

    static if (T.mant_dig == 64 && T.max_exp == 16384)
        enum size = 10; // x87, exclude padding
    else
        enum size = T.sizeof;
    const pa = (cast(ubyte*) &a)[0 .. size];

    // the highest 2 bits of the mantissa should be set, everything else zero
    assert(bittst(pa, T.mant_dig - 1));
    assert(bittst(pa, T.mant_dig - 2));
    foreach(p; 0..T.mant_dig - 2)
        assert(!bittst(pa, p));
}

bool test()
{
        real r1 = real.nan;
        real r2 = 1;
        b = (r1 != r2); assert(b);
        b = (r1 == r2); assert(!b);
        b = (r1 <  r2); assert(!b);
        b = (r1 >  r2); assert(!b);
        b = (r1 <= r2); assert(!b);
        b = (r1 >= r2); assert(!b);

        double d1 = double.nan;
        double d2 = 1;
        b = (d1 != d2); assert(b);
        b = (d1 == d2); assert(!b);
        b = (d1 <  d2); assert(!b);
        b = (d1 >  d2); assert(!b);
        b = (d1 <= d2); assert(!b);
        b = (d1 >= d2); assert(!b);

        float f1 = float.nan;
        float f2 = 1;
        b = (f1 != f2); assert(b);
        b = (f1 == f2); assert(!b);
        b = (f1 <  f2); assert(!b);
        b = (f1 >  f2); assert(!b);
        b = (f1 <= f2); assert(!b);
        b = (f1 >= f2); assert(!b);
        return true;
}

void main()
{
    assert(test());
    test2!float();
    test2!double();
    test2!real();
}