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

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