Created
November 18, 2015 00:22
-
-
Save PiJoules/e9444e57ff22552f71e3 to your computer and use it in GitHub Desktop.
Test I ran to see if there were any faster ways of finding the sum of digits in an integer than looping and dividing by 10.
This file contains 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 <stdio.h> | |
#include <time.h> | |
#include <string.h> | |
/** | |
* Test to see how fast it takes to fund the sum of | |
* the digits of an integer. | |
*/ | |
/** | |
* Traditional method | |
*/ | |
unsigned int test1(unsigned int n){ | |
unsigned int sum = 0; | |
while (n){ | |
sum += n % 10; | |
n /= 10; | |
} | |
return sum; | |
} | |
/** | |
* Using sprintf() for int to char. | |
*/ | |
unsigned int test2(unsigned int n){ | |
char str[] = "0000000000"; // 2^32 base 10 has 10 digits | |
sprintf(str, "%u", n); | |
unsigned int sum = 0, max = strlen(str); | |
int i; | |
for (i = 0; i < max; i++) | |
sum += str[i]-'0'; | |
return sum; | |
} | |
/** | |
* Using sprintf() for int to char. | |
* This time with known length. | |
*/ | |
unsigned int test3(unsigned int n){ | |
char str[] = "000000"; // 2^32 base 10 has 10 digits | |
sprintf(str, "%u", n); | |
unsigned int sum = 0, max = 6; | |
int i; | |
for (i = 0; i < max; i++) | |
sum += str[i]-'0'; | |
return sum; | |
} | |
/** | |
* Using the trick divide by 10 | |
*/ | |
unsigned int test4(unsigned long n){ | |
unsigned int sum = 0; | |
while (n){ | |
sum += n % 10; | |
// n /= 10; | |
n = (n * 0x1999999A) >> 32; | |
} | |
return sum; | |
} | |
/** | |
* Using the trick divide by 10 | |
*/ | |
unsigned int test5(unsigned long n){ | |
unsigned int sum = 0, q, r; | |
while (n){ | |
sum += n % 10; | |
// n /= 10; | |
// n = (n * 0x1999999A) >> 32; | |
q = (n >> 1) + (n >> 2); | |
q = q + (q >> 4); | |
q = q + (q >> 8); | |
q = q + (q >> 16); | |
q = q >> 3; | |
r = n - q*10; | |
n = q + ((r + 6) >> 4); | |
} | |
return sum; | |
} | |
/** | |
* Using the trick divide by 10 | |
*/ | |
unsigned int test6(unsigned long n){ | |
unsigned int sum = 0; | |
unsigned long t; | |
while (n){ | |
// sum += n % 10; | |
// n /= 10; | |
t = (n * 0x1999999A) >> 32; | |
sum += n-t; | |
n = t; | |
} | |
return sum; | |
} | |
int main(int argc, char *argv[]){ | |
clock_t t; // microsecond resolution | |
unsigned int n = 123456, i, num = 10000; | |
unsigned int sum; | |
unsigned long timesum, j, times = 1000; | |
timesum = 0; | |
for (j = 0; j < times; j++){ | |
t = clock(); | |
for (i = 0; i < num; i ++) | |
sum = test1(n); | |
timesum += clock()-t; | |
} | |
if (sum == 21) | |
printf("Test1: \t%luus\n", timesum/times); | |
else | |
printf("Test1 returned incorrect answer\n"); | |
timesum = 0; | |
for (j = 0; j < times; j++){ | |
t = clock(); | |
for (i = 0; i < num; i ++) | |
sum = test2(n); | |
timesum += clock()-t; | |
} | |
if (sum == 21) | |
printf("Test2: \t%luus\n", timesum/times); | |
else | |
printf("Test2 returned incorrect answer\n"); | |
timesum = 0; | |
for (j = 0; j < times; j++){ | |
t = clock(); | |
for (i = 0; i < num; i ++) | |
sum = test3(n); | |
timesum += clock()-t; | |
} | |
if (sum == 21) | |
printf("Test3: \t%luus\n", timesum/times); | |
else | |
printf("Test3 returned incorrect answer\n"); | |
timesum = 0; | |
for (j = 0; j < times; j++){ | |
t = clock(); | |
for (i = 0; i < num; i ++) | |
sum = test4(n); | |
timesum += clock()-t; | |
} | |
if (sum == 21) | |
printf("Test4: \t%luus\n", timesum/times); | |
else | |
printf("Test4 returned incorrect answer\n"); | |
timesum = 0; | |
for (j = 0; j < times; j++){ | |
t = clock(); | |
for (i = 0; i < num; i ++) | |
sum = test5(n); | |
timesum += clock()-t; | |
} | |
if (sum == 21) | |
printf("Test5: \t%luus\n", timesum/times); | |
else | |
printf("Test5 returned incorrect answer\n"); | |
timesum = 0; | |
for (j = 0; j < times; j++){ | |
t = clock(); | |
for (i = 0; i < num; i ++) | |
sum = test6(n); | |
timesum += clock()-t; | |
} | |
if (sum == 21) | |
printf("Test6: \t%luus\n", timesum/times); | |
else | |
printf("Test6 returned incorrect answer\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment