OILS / mycpp / gc_mops_test.cc View on Github | oilshell.org

182 lines, 117 significant
1#include "mycpp/gc_mops.h"
2
3#include <cinttypes>
4
5#include "mycpp/runtime.h"
6#include "vendor/greatest.h"
7
8TEST sizeof_test() {
9 // 8 bytes
10 log("size = %d", sizeof(long long));
11 // 16 bytes! Supposed by GCC and Clang on SOME targets for ~15 years
12 // log("size = %d", sizeof(__int128_t));
13 PASS();
14}
15
16TEST bigint_test() {
17 // You need to instantiate it as a BigInt, the constant (1) doesn't work
18 // And also use %ld
19
20 mops::BigInt i = mops::BigInt{1} << 31;
21 log("bad i = %d", i); // bug
22 log("good i = %ld", i);
23 log("");
24
25 mops::BigInt i2 = mops::BigInt{1} << 32;
26 log("good i2 = %ld", i2);
27 log("");
28
29 mops::BigInt i3 = i2 + i2;
30 log("good i3 = %ld", i3);
31 log("");
32
33 int64_t j = int64_t{1} << 31;
34 log("bad j = %d", j); // bug
35 log("good j = %ld", j);
36
37 PASS();
38}
39
40TEST static_cast_test() {
41 // These conversion ops are currently implemented by static_cast<>
42
43 auto big = mops::BigInt{1} << 31;
44
45 // Turns into a negative number
46 int i = mops::BigTruncate(big);
47 log("i = %d", i);
48
49 // Truncates float to int. TODO: Test out Oils behavior.
50 float f = 3.14f;
51 auto fbig = mops::FromFloat(f);
52 log("%f -> %ld", f, fbig);
53
54 f = 3.99f;
55 fbig = mops::FromFloat(f);
56 log("%f = %ld", f, fbig);
57
58 // OK this is an exact integer
59 f = mops::ToFloat(big);
60 log("f = %f", f);
61 ASSERT_EQ_FMT(f, 2147483648.0, "%f");
62
63 PASS();
64}
65
66TEST conversion_test() {
67 mops::BigInt int_min{INT64_MIN};
68 mops::BigInt int_max{INT64_MAX};
69 BigStr* int_str;
70
71 int_str = mops::ToStr(15);
72 ASSERT(str_equals0("15", int_str));
73 print(mops::ToStr(int_min));
74 print(mops::ToStr(int_max));
75 print(kEmptyString);
76
77 int_str = mops::ToOctal(15);
78 ASSERT(str_equals0("17", int_str));
79 print(mops::ToOctal(int_min));
80 print(mops::ToOctal(int_max));
81 print(kEmptyString);
82
83 int_str = mops::ToHexLower(15);
84 ASSERT(str_equals0("f", int_str));
85 print(mops::ToHexLower(int_min));
86 print(mops::ToHexLower(int_max));
87 print(kEmptyString);
88
89 int_str = mops::ToHexUpper(15);
90 ASSERT(str_equals0("F", int_str));
91 print(mops::ToHexUpper(int_min));
92 print(mops::ToHexUpper(int_max));
93 print(kEmptyString);
94
95 PASS();
96}
97
98TEST float_test() {
99 double f = mops::ToFloat(1) / mops::ToFloat(3);
100 // double f = static_cast<double>(1) / static_cast<double>(3);
101
102 log("one third = %f", f);
103 // wtf, why does this has a 43
104 log("one third = %.9g", f);
105 log("one third = %.10g", f);
106 log("one third = %.11g", f);
107
108 f = mops::ToFloat(2) / mops::ToFloat(3);
109 log("one third = %.9g", f);
110 log("one third = %.10g", f);
111
112 double one = mops::ToFloat(1);
113 double three = mops::ToFloat(3);
114 log("one = %.10g", one);
115 log("three = %.10g", three);
116 log("one / three = %.10g", one / three);
117
118 PASS();
119}
120
121TEST gcc_clang_overflow_test() {
122 bool ok;
123
124 // Compute (1L << 63) - 1L without overflow!
125 int64_t a = INT64_C(1) << 62;
126 a += (INT64_C(1) << 62) - INT64_C(1);
127
128 int64_t b = 0;
129 int64_t result = 0;
130
131 for (b = 0; b <= 1; ++b) {
132#if LONG_MAX == INT64_MAX
133 ok = __builtin_saddl_overflow(a, b, &result);
134#else
135 // 32-bit, we have to use long long?
136 ok = __builtin_saddll_overflow(a, b, &result);
137#endif
138 if (ok) {
139 printf("%" PRId64 " + %" PRId64 " = signed add long overflow!\n", a, b);
140 } else {
141 printf("%" PRId64 " + %" PRId64 " = %" PRId64 "\n", a, b, result);
142 }
143 }
144
145 a = INT64_C(1) << 62;
146 for (b = 1; b <= 2; ++b) {
147#if LONG_MAX == INT64_MAX
148 ok = __builtin_smull_overflow(a, b, &result);
149#else
150 ok = __builtin_smulll_overflow(a, b, &result);
151#endif
152
153 if (ok) {
154 printf("%" PRId64 " * %" PRId64 " = signed mul long overflow!\n", a, b);
155 } else {
156 printf("%" PRId64 " * %" PRId64 " = %" PRId64 "\n", a, b, result);
157 }
158 }
159
160 PASS();
161}
162
163GREATEST_MAIN_DEFS();
164
165int main(int argc, char** argv) {
166 gHeap.Init();
167
168 GREATEST_MAIN_BEGIN();
169
170 RUN_TEST(sizeof_test);
171 RUN_TEST(bigint_test);
172 RUN_TEST(static_cast_test);
173 RUN_TEST(conversion_test);
174 RUN_TEST(float_test);
175 RUN_TEST(gcc_clang_overflow_test);
176
177 gHeap.CleanProcessExit();
178
179 GREATEST_MAIN_END();
180
181 return 0;
182}