• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stillwater-sc / universal / 30670440874

31 Jul 2026 10:35PM UTC coverage: 85.25% (+0.001%) from 85.249%
30670440874

Pull #1285

github

web-flow
Merge 8c44fe4ed into 228a57c15
Pull Request #1285: fix(internal): clear -Wsign-conversion in blockbinary + blocksignificand (#1280)

42 of 45 new or added lines in 3 files covered. (93.33%)

41718 of 48936 relevant lines covered (85.25%)

7271862.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.9
/internal/blockbinary/logic/shift_left.cpp
1
// shift_left.cpp: functional tests for block binary number shifts
2
//
3
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
4
// SPDX-License-Identifier: MIT
5
//
6
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
7
#include <universal/utility/directives.hpp>
8
#include <universal/utility/long_double.hpp>
9
#include <iostream>
10
#include <iomanip>
11

12
#include <universal/internal/blockbinary/blockbinary.hpp>
13
#include <universal/verification/test_status.hpp>
14
#include <universal/verification/test_reporters.hpp>
15
#include <universal/verification/blockbinary_test_status.hpp>
16

17
// enumerate all shift left cases for an blockbinary<nbits,BlockType> configuration
18
template<size_t nbits, typename BlockType = uint8_t>
19
int VerifyLeftShift(bool reportTestCases) {
30✔
20
        using namespace sw::universal;
21
        using BlockBinary = blockbinary<nbits, BlockType>;
22

23
        if (reportTestCases) std::cout << type_tag(BlockBinary()) << '\n';
30✔
24

25
        // take 1 and shift it left in all possible strides
26
        int nrOfFailedTests = 0;
30✔
27
        BlockBinary a, result;
28
        int64_t shiftRef, resultRef;
29
        for (size_t i = 0; i < nbits + 1; i++) {
782✔
30
                if (i >= 64) {
752✔
31
                        shiftRef = 0; // shift all bits out
2✔
32
                }
33
                else {
34
                        shiftRef = static_cast<int64_t>(0xFFFF'FFFF'FFFF'FFFFull << i);
750✔
35
                }
36
                if (i == nbits) shiftRef = 0; // shift all bits out
752✔
37

38
                a = -1;
752✔
39
                result = a << long(i);
752✔
40
                resultRef = (long long)result;
752✔
41

42
                if (shiftRef != resultRef) {
752✔
43
                        nrOfFailedTests++;
×
44
                        if (reportTestCases) ReportArithmeticShiftError("FAIL", "<<", a, i, result, resultRef);
×
45
                }
46
                else {
47
                        if (reportTestCases) ReportArithmeticShiftSuccess("PASS", "<<", a, i, result, resultRef);
752✔
48
                }
49
                if (nrOfFailedTests > 100) return nrOfFailedTests;
752✔
50
        }
51
        return nrOfFailedTests;
30✔
52
}
53

54
// verify that operator<<= preserves the invariant that bits outside nbits are nulled,
55
// so the raw-block iszero()/operator== stay correct. VerifyLeftShift above cannot catch
56
// this because (long long)result masks the stray high bits away before comparison. #1280
57
template<size_t nbits, typename BlockType = uint8_t>
58
int VerifyLeftShiftInvariant(bool reportTestCases) {
5✔
59
        using namespace sw::universal;
60
        using BlockBinary = blockbinary<nbits, BlockType>;
61
        int nrOfFailedTests = 0;
5✔
62
        for (unsigned start = 0; start < nbits; ++start) {
79✔
63
                for (int i = 0; i < static_cast<int>(nbits) + 1; ++i) {
1,294✔
64
                        BlockBinary shifted; shifted.clear(); shifted.setbit(start);
1,220✔
65
                        shifted <<= i;
1,220✔
66
                        // canonical value: reconstruct via operator=(long long), which nulls leading bits.
67
                        // a raw-block operator== then flags any stray bits left in the unused MSU storage.
68
                        BlockBinary canonical; canonical = static_cast<long long>(shifted);
1,220✔
69
                        if (shifted != canonical || shifted.iszero() != canonical.iszero()) {
1,220✔
NEW
70
                                ++nrOfFailedTests;
×
NEW
71
                                if (reportTestCases) std::cout << "FAIL: setbit(" << start << ") <<= " << i
×
NEW
72
                                        << " left stray MSU bits\n";
×
73
                        }
74
                }
75
        }
76
        return nrOfFailedTests;
5✔
77
}
78

79
// run the MSU-invariant check across a few multi-block configurations (uint8 and uint16 limbs)
80
int VerifyLeftShiftInvariants(bool reportTestCases) {
1✔
81
        int f = 0;
1✔
82
        f += VerifyLeftShiftInvariant<12, uint8_t>(reportTestCases);
1✔
83
        f += VerifyLeftShiftInvariant<13, uint8_t>(reportTestCases);
1✔
84
        f += VerifyLeftShiftInvariant<20, uint8_t>(reportTestCases);
1✔
85
        f += VerifyLeftShiftInvariant<17, uint16_t>(reportTestCases);
1✔
86
        f += VerifyLeftShiftInvariant<12, uint16_t>(reportTestCases);
1✔
87
        return f;
1✔
88
}
89

90

91
// Regression testing guards: typically set by the cmake configuration, but MANUAL_TESTING is an override
92
#define MANUAL_TESTING 0
93
// REGRESSION_LEVEL_OVERRIDE is set by the cmake file to drive a specific regression intensity
94
// It is the responsibility of the regression test to organize the tests in a quartile progression.
95
#undef REGRESSION_LEVEL_OVERRIDE
96
#ifndef REGRESSION_LEVEL_OVERRIDE
97
#undef REGRESSION_LEVEL_1
98
#undef REGRESSION_LEVEL_2
99
#undef REGRESSION_LEVEL_3
100
#undef REGRESSION_LEVEL_4
101
#define REGRESSION_LEVEL_1 1
102
#define REGRESSION_LEVEL_2 1
103
#define REGRESSION_LEVEL_3 1
104
#define REGRESSION_LEVEL_4 1
105
#endif
106

107
int main()
1✔
108
try {
109
        using namespace sw::universal;
110
        
111
        std::string test_suite  = "blockbinary logic left shifting";
2✔
112
        std::string test_tag    = "arithmetic/logic left shift";
1✔
113
        bool reportTestCases    = false;
1✔
114
        int nrOfFailedTestCases = 0;
1✔
115

116
        std::cout << test_suite << '\n';
1✔
117

118
#if MANUAL_TESTING
119

120
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<12>(true), "blockbinary<12>", test_tag);
121

122
        {
123
                blockbinary<12> a;
124
                a.setbits(0x800);
125
                std::cout << to_hex(a) << ' ';
126
                a <<= 8;
127
                std::cout << to_hex(a) << '\n';
128
        }
129
        {
130
                blockbinary<8> a;
131
                for (int i = 0; i < 16; ++i) {
132
                        a.setbits(0x80);
133
                        a <<= i;
134
                        std::cout << to_binary(a, true) << ' ' << (long long)(a) << "  right shift by " << i << '\n';
135
                }
136
        }
137

138
        ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
139
        return EXIT_SUCCESS; // ignore failures
140
#else
141

142
#if REGRESSION_LEVEL_1
143
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<2>(reportTestCases), "blockbinary<2>", test_tag);
2✔
144
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<3>(reportTestCases), "blockbinary<3>", test_tag);
2✔
145
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<4>(reportTestCases), "blockbinary<4>", test_tag);
2✔
146
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<5>(reportTestCases), "blockbinary<5>", test_tag);
2✔
147
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<6>(reportTestCases), "blockbinary<6>", test_tag);
2✔
148
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<7>(reportTestCases), "blockbinary<7>", test_tag);
2✔
149
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<8>(reportTestCases), "blockbinary<8>", test_tag);
2✔
150
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<9>(reportTestCases), "blockbinary<9>", test_tag);
2✔
151
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<10>(reportTestCases), "blockbinary<10>", test_tag);
2✔
152
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<11>(reportTestCases), "blockbinary<11>", test_tag);
2✔
153
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<12>(reportTestCases), "blockbinary<12>", test_tag);
2✔
154
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<13>(reportTestCases), "blockbinary<13>", test_tag);
2✔
155
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<14>(reportTestCases), "blockbinary<14>", test_tag);
2✔
156
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<15>(reportTestCases), "blockbinary<15>", test_tag);
2✔
157
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<16>(reportTestCases), "blockbinary<16>", test_tag);
2✔
158
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<17>(reportTestCases), "blockbinary<17>", test_tag);
2✔
159

160
        // #1280: left shift must not leave stray bits in the unused MSU storage (raw-block invariant)
161
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShiftInvariants(reportTestCases), "MSU invariant", test_tag);
2✔
162

163
#endif
164

165
#if REGRESSION_LEVEL_2
166
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<18>(reportTestCases), "blockbinary<18>", test_tag);
2✔
167
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<20>(reportTestCases), "blockbinary<20>", test_tag);
2✔
168
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<24>(reportTestCases), "blockbinary<24>", test_tag);
2✔
169
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<28>(reportTestCases), "blockbinary<28>", test_tag);
2✔
170
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<32>(reportTestCases), "blockbinary<32>", test_tag);
2✔
171
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<40>(reportTestCases), "blockbinary<40>", test_tag);
2✔
172
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<48>(reportTestCases), "blockbinary<48>", test_tag);
2✔
173
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<56>(reportTestCases), "blockbinary<56>", test_tag);
2✔
174
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<64>(reportTestCases), "blockbinary<64>", test_tag);
2✔
175
#endif
176

177
#if REGRESSION_LEVEL_3
178
        // using a more efficient storage class
179
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<32,uint32_t>(reportTestCases), "blockbinary<32,uint32_t>", test_tag);
2✔
180
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<40,uint32_t>(reportTestCases), "blockbinary<40,uint32_t>", test_tag);
2✔
181
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<48, uint32_t>(reportTestCases), "blockbinary<48,uint32_t>", test_tag);
2✔
182
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<56, uint32_t>(reportTestCases), "blockbinary<56,uint32_t>", test_tag);
2✔
183
        nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<64, uint32_t>(reportTestCases), "blockbinary<64,uint32_t>", test_tag);
1✔
184
#endif
185

186
#if        REGRESSION_LEVEL_4        
187
        // can't test this with VerifyLeftShift since we don't have a >64bit native integer type
188
        //nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<128, uint32_t>(reportTestCases), "blockbinary<128,uint32_t>", test_tag);
189
        //nrOfFailedTestCases += ReportTestResult(VerifyLeftShift<256, uint32_t>(reportTestCases), "blockbinary<256,uint32_t>", test_tag);
190

191
#endif
192

193
        ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
1✔
194
        return (nrOfFailedTestCases > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
1✔
195
#endif  // MANUAL_TESTING
196
}
1✔
197
catch (char const* msg) {
×
198
        std::cerr << msg << std::endl;
×
199
        return EXIT_FAILURE;
×
200
}
×
201
catch (const std::runtime_error& err) {
×
202
        std::cerr << "Uncaught runtime exception: " << err.what() << std::endl;
×
203
        return EXIT_FAILURE;
×
204
}
×
205
catch (...) {
×
206
        std::cerr << "Caught unknown exception" << std::endl;
×
207
        return EXIT_FAILURE;
×
208
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc