2 // Proposition for fixing unix time overflow.
3 // copyright 2024, David Polakovic, licensed under GPLv3
11 // First four functions are commented more heavily because it
12 // was my first time doing such a thing...
14 // Initialize a BigInt from a string
16 int *digits; // Pointer to an array of digits
17 int size; // Number of digits
20 // Define a structure for a BigInt, which is an integer with arbitrary precision
21 BigInt initBigInt(const char *str) {
22 int len = strlen(str); // Get the length of the string
23 BigInt num; // Declare a BigInt variable
24 num.size = len; // Set the size of BigInt to the length of the string
25 num.digits = (int *)malloc(len * sizeof(int)); // Alloc memory for the digits
26 for (int i = 0; i < len; i++) { // Convert digits to int and store them in reverse
27 num.digits[i] = str[len - 1 - i] - '0';
29 return num; // Return the initialized BigInt
32 // Free the memory allocated for a BigInt.
33 void freeBigInt(BigInt *num) {
34 free(num->digits); // Free the memory allocated for digits
35 num->digits = NULL; // Set the digits pointer to NULL
36 num->size = 0; // Set the size to 0
39 void printBigInt(BigInt *num) {
40 int leadingZero = 1; // Flag to handle leading zeros
41 for (int i = num->size - 1; i >= 0; i--) { // Iterate digits in reverse order
42 if (num->digits[i] != 0 || !leadingZero) { // Skip leading zeros
43 printf("%d", num->digits[i]); // Print the digit
44 leadingZero = 0; // Clear the leading zero flag
48 printf("0"); // Print 0 if all digits are zero
53 int isGreaterOrEqual(BigInt *a, BigInt *b) {
54 if (a->size > b->size) return 1; // Checks digits count
55 if (a->size < b->size) return 0;
56 for (int i = a->size - 1; i >= 0; i--) { // Compare digits from most significant to least
57 if (a->digits[i] > b->digits[i]) return 1;
58 if (a->digits[i] < b->digits[i]) return 0;
63 // NOTE: this function is commented by SkyNet because I got lost in it...
64 void subtractBigInt(BigInt *a, BigInt *b, BigInt *result) {
65 result->size = a->size; // Set the size of result to the size of a
66 result->digits = (int *)calloc(result->size, sizeof(int)); // Allocate memory and initialize to zero
67 int carry = 0; // Initialize carry to 0
68 for (int i = 0; i < a->size; i++) { // Iterate over the digits
69 int digit1 = a->digits[i]; // Get the digit from a
70 int digit2 = (i < b->size) ? b->digits[i] : 0; // Get the digit from b or 0 if out of range
71 int sub = digit1 - digit2 - carry; // Perform the subtraction
72 if (sub < 0) { // Handle borrowing
78 result->digits[i] = sub; // Store the result digit
80 while (result->size > 1 && result->digits[result->size - 1] == 0) {
81 result->size--; // Remove leading zeros
86 void divideBigInt(BigInt *dividend, BigInt *divisor, BigInt *result) {
87 // Initialize result BigInt size and allocate memory for digits
88 result->size = dividend->size;
89 result->digits = (int *)calloc(result->size, sizeof(int));
91 // Initialize current BigInt for intermediate calculations
94 current.digits = (int *)calloc(dividend->size, sizeof(int));
96 // Iterate over each digit of the dividend from the highest to the lowest
97 for (int i = dividend->size - 1; i >= 0; i--) {
98 // Shift digits in the current BigInt to left
99 for (int j = current.size; j > 0; j--) {
100 current.digits[j] = current.digits[j - 1];
102 // Add the next digit of the dividend to the current BigInt
103 current.digits[0] = dividend->digits[i];
106 // Remove leading zeros in the current BigInt
107 while (current.size > 1 && current.digits[current.size - 1] == 0) {
112 // Perform division if possible
113 while (isGreaterOrEqual(¤t, divisor)) {
115 subtractBigInt(¤t, divisor, &tempResult);
116 free(current.digits);
117 current = tempResult;
121 // Store the quotient in the result
122 result->digits[i] = count;
125 // Remove leading zeros in the result
126 while (result->size > 1 && result->digits[result->size - 1] == 0) {
130 free(current.digits);
134 // Only to be used in moduloBigInt
135 void multiplyBigInt(BigInt *a, BigInt *b, BigInt *result) {
136 result->size = a->size + b->size;
137 result->digits = (int *)calloc(result->size, sizeof(int));
139 for (int i = 0; i < a->size; i++) {
141 for (int j = 0; j < b->size; j++) {
142 int product = a->digits[i] * b->digits[j] + result->digits[i + j] + carry;
143 result->digits[i + j] = product % 10;
144 carry = product / 10;
146 result->digits[i + b->size] += carry;
149 while (result->size > 1 && result->digits[result->size - 1] == 0) {
154 // Just for validation...
155 void moduloBigInt(BigInt *dividend, BigInt *divisor, BigInt *result) {
156 BigInt tempDivResult;
157 divideBigInt(dividend, divisor, &tempDivResult);
159 BigInt tempMulResult;
160 multiplyBigInt(&tempDivResult, divisor, &tempMulResult);
162 subtractBigInt(dividend, &tempMulResult, result);
164 freeBigInt(&tempDivResult);
165 freeBigInt(&tempMulResult);
169 BigInt loadCurrentUnixTime() {
170 time_t currentTime = time(NULL);
172 snprintf(timeStr, sizeof(timeStr), "%ld", currentTime);
173 return initBigInt(timeStr);
176 // Inverse function to substractBigInt
177 void addBigInt(BigInt *a, BigInt *b, BigInt *result) {
178 int maxSize = (a->size > b->size) ? a->size : b->size;
179 result->size = maxSize + 1; // Extra space for possible carry
180 result->digits = (int *)calloc(result->size, sizeof(int));
183 for (int i = 0; i < maxSize; i++) {
184 int digit1 = (i < a->size) ? a->digits[i] : 0;
185 int digit2 = (i < b->size) ? b->digits[i] : 0;
186 int sum = digit1 + digit2 + carry;
187 result->digits[i] = sum % 10;
192 result->digits[maxSize] = carry;
198 // Just for personal validation...
199 int countDigitsBigInt(BigInt *num) {
201 for (int i = 0; i < num->size; i++) {
209 BigInt time_f = loadCurrentUnixTime();
210 BigInt year_s = initBigInt("31536000"); // Seconds in a year
216 printf("Unix Time: ");
217 printBigInt(&time_f);
219 // Result of modulo time_f % year_s
221 moduloBigInt(&time_f, &year_s, &modResult);
222 printf("\tModulo: ");
223 printBigInt(&modResult);
225 // Digit counter of unix time value (only in Integer boundary)
226 int numDigits = countDigitsBigInt(&time_f);
227 printf("\t(%d digits)", numDigits);
229 // Year (time_f / year_s) + 1970
230 BigInt yearAddition = initBigInt("1970");
233 divideBigInt(&time_f, &year_s, &divResult);
234 addBigInt(&divResult, &yearAddition, &finalYear);
235 printf("\t\tYear: ");
236 printBigInt(&finalYear);
241 // Increment num1 by 1
242 BigInt one = initBigInt("1");
243 BigInt incrementedTime;
244 addBigInt(&time_f, &one, &incrementedTime);
247 time_f = incrementedTime; // Update num1 to the incremented value
248 freeBigInt(&divResult);
249 freeBigInt(&modResult);
250 freeBigInt(&finalYear);
251 freeBigInt(&yearAddition);