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:  <%-{-{-{-<


In reply to Re^3: Faster Luhn Check Digit Calculation? by AnomalousMonk
in thread Faster Luhn Check Digit Calculation? by kschwab

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.