aboutsummaryrefslogtreecommitdiff
path: root/Client/ThirdParty/fpm/tests/conversion.cpp
blob: 0b70da56b65745c00e5f6576e680017b84308c01 (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
98
99
100
101
102
103
104
105
#include "common.hpp"
#include <utility>

using P = fpm::fixed_16_16;
using Q = fpm::fixed_24_8;

TEST(conversion, construction)
{
    P x;
}

TEST(conversion, copy)
{
    const P x(12);

    // Copy ctor
    P y(x);
    EXPECT_EQ(P(12), y);

    // Copy assignment
    P z = x;
    EXPECT_EQ(P(12), y);
}

TEST(conversion, move)
{
    const P x(12);

    // Move ctor
    P y(std::move(x));
    EXPECT_EQ(P(12), y);

    // Move assignment
    P z = std::move(x);
    EXPECT_EQ(P(12), y);
}

TEST(conversion, floats)
{
    EXPECT_EQ(1.125, static_cast<double>(P{1.125f}));
    EXPECT_EQ(1.125, static_cast<double>(P{1.125}));
}

TEST(conversion, float_rounding)
{
    // Small number of fraction bits to test rounding
    using Q = fpm::fixed<std::int32_t, std::int64_t, 2>;

    EXPECT_EQ(1.25, static_cast<double>(Q{1.125}));
    EXPECT_EQ(1.5, static_cast<double>(Q{1.375}));
    EXPECT_EQ(-1.25, static_cast<double>(Q{-1.125}));
    EXPECT_EQ(-1.5, static_cast<double>(Q{-1.375}));
}

TEST(conversion, ints)
{
    EXPECT_EQ(-125, static_cast<int>(P{-125}));
    EXPECT_EQ(-125l, static_cast<long>(P{-125l}));
    EXPECT_EQ(-125ll, static_cast<long long>(P{-125ll}));

    EXPECT_EQ(125u, static_cast<unsigned int>(P{125u}));
    EXPECT_EQ(125lu, static_cast<unsigned long>(P{125lu}));
    EXPECT_EQ(125llu, static_cast<unsigned long long>(P{125llu}));
}

TEST(conversion, fixed_point)
{
    EXPECT_EQ(P(-1), P::from_fixed_point<0>(-1));
    EXPECT_EQ(P(1), P::from_fixed_point<0>(1));

    EXPECT_EQ(P(-1.125), P::from_fixed_point<4>(-18));
    EXPECT_EQ(P(1.125), P::from_fixed_point<4>(18));

    // This should round up to 1
    EXPECT_EQ(P(-1), P::from_fixed_point<20>(-1048575));
    EXPECT_EQ(P(1), P::from_fixed_point<20>(1048575));
}

TEST(conversion, fixed_to_fixed)
{
    EXPECT_EQ(Q(1), Q(P(1)));
    EXPECT_EQ(Q(1), Q(P(1)));

    // Conversion to fewer fraction bits should round
    EXPECT_EQ(Q::from_raw_value(0x13), Q(P::from_raw_value(0x12ff)));
    EXPECT_EQ(Q::from_raw_value(0x12), Q(P::from_raw_value(0x127f)));
    EXPECT_EQ(Q::from_raw_value(-0x13), Q(P::from_raw_value(-0x12ff)));
    EXPECT_EQ(Q::from_raw_value(-0x12), Q(P::from_raw_value(-0x127f)));

    // Conversion to more fraction bits should zero-extend
    EXPECT_EQ(P::from_raw_value(0x1200), P(Q::from_raw_value(0x12)));
    EXPECT_EQ(P::from_raw_value(-0x1200), P(Q::from_raw_value(-0x12)));

    {
        // Assignment requires explicit conversion via construction
        P p(1);
        Q q = Q(p);
        EXPECT_EQ(Q(1), q);
    }

    // Conversion to a smaller base type should truncate the upper bits
    using S1 = fpm::fixed<std::int8_t, std::int16_t, 1>;
    EXPECT_EQ(0x56, S1(P::from_raw_value(0x79AB1000)).raw_value());
    EXPECT_EQ(-0x56, S1(P::from_raw_value(-0x79AB1000)).raw_value());
}