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

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