Last active
December 24, 2020 19:08
-
-
Save kLiHz/421f1e96597ac76b69dc1f49f2868723 to your computer and use it in GitHub Desktop.
Convert signed 64-bit int
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 *) # // 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