Skip to content

Instantly share code, notes, and snippets.

@PiJoules
Created November 18, 2015 00:22
Show Gist options
  • Save PiJoules/e9444e57ff22552f71e3 to your computer and use it in GitHub Desktop.
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.
#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