Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re^3: Faster Luhn Check Digit Calculation?

by AnomalousMonk (Archbishop)
on Dec 02, 2018 at 02:25 UTC ( [id://1226611]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Faster Luhn Check Digit Calculation?
in thread Faster Luhn Check Digit Calculation?

Here's another twist that might squeeze out a few more computrons: use array literals (if that's the correct terminology; introduced with C99 IIRC; I assume Inline::C supports C99) to compile the arrays rather than building local arrays on each subroutine call (if you don't want to just declare the arrays static| static const, which also works | should work). I haven't looked at the assembler output, but the idea (the hope?) is that the compiler would make these statics. There are two versions of the function below; both work. One is more heavily macro-ized because I wanted to see how far I could push this approach; for reasons of maintainability, I'm not sure I'd want it in production code. Only minimal testing has been done; I leave that to you :).

t_array_literal_1.c:

// t_array_literal_1.c 01dec18waw // compile: // gcc -std=c99 t_array_literal_1.c #include "stdio.h" #include "string.h" #include "stdlib.h" #define elementsof(ra) (sizeof(ra) / sizeof(ra[0])) int cd4_a (char *); int cd4_b (char *); void main (void) { char * suffices[] = { "000", "999", "100", "020", "003", "123", }; for (size_t i = 0; i < elementsof(suffices); ++i) { char ccn[20] = "401135000000"; strcat(ccn, suffices[i]); int cda = cd4_a(ccn); int cdb = cd4_b(ccn); // cdb = 8; // for testing printf("ccn: '%s' a: %d b: %d", ccn, cda, cdb); if (cda != cdb) { printf(" (digits differ: stopping) \n", cda, cdb); exit(1); } printf("\n"); } } int cd4_a( char *ccn ) { // from pm#1226599 int total = 0; int i; int co9[]={0,2,4,6,8,1,3,5,7,9}; // or maybe just make these arra +ys static? int straight[]={1,3,5,7,9,11,13}; int adjusted[]={0,2,4,6,8,10,12,14}; for (i=0;i<7;i++) { total += ccn[straight[i]]-48; } for (i=0;i<8;i++) { total += co9[ccn[adjusted[i]]-48]; } total *=9; return total %10; } #define X2_CO9 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 #define STRAIGHT_I 1, 3, 5, 7, 9, 11, 13 #define ADJUSTED_I 0, 2, 4, 6, 8, 10, 12, 14 int cd4_b (char * ccn) { int total = 0; for (int i = 0; i < 7; i++) { total += ccn[ ((int []){ STRAIGHT_I })[i] ] - (int)'0'; } for (int i = 0; i < 8; i++) { total += ((int []){ X2_CO9 })[ ccn[ ((int []){ ADJUSTED_I })[i +] ] - (int)'0']; } total *= 9; return total % 10; } // #define X2_CO9(n) (((int []){ 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 })[n]) // #define STRAIGHT_I(i) (((int []){ 1, 3, 5, 7, 9, 11, 13 })[i]) // #define ADJUSTED_I(i) (((int []){ 0, 2, 4, 6, 8, 10, 12, 14 })[i]) // // int cd4_b (char * ccn) { // // int total = 0; // // for (int i = 0; i < 7; i++) { // total += ccn[ STRAIGHT_I(i) ] - (int)'0'; // } // // for (int i = 0; i < 8; i++) { // total += X2_CO9( ccn[ ADJUSTED_I(i) ] - (int)'0' ); // } // // total *= 9; // return total % 10; // // }


Give a man a fish:  <%-{-{-{-<

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1226611]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (4)
As of 2024-04-26 00:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found