Skip to content

Instantly share code, notes, and snippets.

@kLiHz
Last active December 24, 2020 19:08
Show Gist options
  • Save kLiHz/421f1e96597ac76b69dc1f49f2868723 to your computer and use it in GitHub Desktop.
Save kLiHz/421f1e96597ac76b69dc1f49f2868723 to your computer and use it in GitHub Desktop.
Convert signed 64-bit int
#include <iostream>
#include <chrono>
void print_I64(long long num) {
// Try NOT using `if` statement, since it will make the program slower
char str[32] = {0};
short idx = 31;
long long sign = num >> 63; // -1 for negative, 0 for positive
// by doing this we assume that the spaces are filled with num's sign bit
num ^= sign;
num -= sign;
// now we are sure that num is positive,
// and this seems to be faster than using normal ways to get absolute value ...
// possble ways can be: int is_postive = (x > 0); x *= (2 * is_positive - 1);
do {
--idx;
str[idx] = num % 10 + '0';
// but you can choose NOT to get a absolute value and
// acquire the character by using a predefined string
// like "9876543210123456789", and index it by `num % 10 + 9`
} while (num /= 10);
// if (sign) str[--idx] = '-'; // if we're going to eliminate all `if` statement ...
str[idx] = '-' * (-sign) + str[idx] * (1 - sign); // using this also works
std::cout << &str[idx]; // You can comment this line out when counting time cost
}
// above we are preforming directly on a 64-bit 'int', I'm wondering whether it would be
// faster to split the 64-bit 'int' into two 32-bit 'int's on 32-bit machine
void print_I64_split(long long num) {
// 'long long int' has 8 Bytes, which is 64 bit
char str[32] = {0};
short idx = 31;
int * ptr = (int *) &num; // points to the block which stores the first 32 bit of 'num'
int sign = *(ptr + 1); sign >>= 31; // -1 for negative, 0 for positive
*(ptr) ^= sign;
*(ptr + 1) ^= sign;
num -= sign;
do {
--idx;
str[idx] = num % 10 + '0';
} while (num /= 10);
if (sign) str[--idx] = '-';
std::cout << &str[idx];
}
int main()
{
long long num;
std::cin >> num;
std::chrono::steady_clock sc;
auto start = sc.now();
for (int i = 0; i < 10000; ++i)
print_I64(num);
auto end = sc.now();
auto time_span = static_cast<std::chrono::duration<double>>(end - start);
std::cout << "operation took: " << time_span.count() << " seconds." << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment