Computer program
I've decided against supply you with actual code. The reason is that if you ran my code, you'd just be duplicating what I've already done. I think it better for each of us to use our own approaches.
But I don't think any harm will be done by giving you some hints.
Here is what I did to speed up the split process:
1. Determine the correct Hit, Stand, Double strategy.
2. For each pair, generate every possible card combination starting with that card using the above strategy. The first card is held in a file section header, and only the subsequent cards are recorded in a struct:
#define byte unsigned char;
{ char hand[14]; byte score; byte ways; byte bet; }
Yes, you need 14! Consider the hand AAAAAAAA4AAAAA (remember, soft 18 sometimes hits) -- 14 cards! Only 13 will be stored in the struct, but the way I calculated probs I needed the cards to be followed by at least one null char:
ptr = (char far*)&[the struct].hand;
numerator = 1.0;
while ( card = *ptr++ )
{...if ( !card_counts[card] )
........return;
....numerator *= card_counts[card]--;
}
[ignore the ".'s," they're just for spacing purposes]
The denominator is always the same for each number of cards, which can easily be determined by the strlen() function. IOW, for six decks the denominator for the one card will always be 309 (because two of the pair card and one of the dealer upcard will already have been removed from the shoe). The denominator for two cards will always be 309 * 308, etc. Thus you can precalculate all denominators and save a great deal of double precision math number crunching time.
As new combos are generated, the cards in the hand are sorted and the previously generated combos are searched for a match, and "ways" in the existing struct incremented for each match; or the combo added if no match.
This isolates each *unique* combination and records the number of times it occurs.
3. Once all unique combos are determined, they are sorted in ascending order of probability of occurance (remember to utilize the "ways" member when doing this), and written out to a disk file.
4. Do the same thing (2 & 3 above) with all dealer combos.
Now, with both files sorted in probability order, you will be handling the combinations of player and dealer structs in ascending order of probability, which automatically minimizes rounding errors, provided you handle it properly. I did it by accumulating the probs separately for each stage (first hand, second hand, dealer hand). IOW, the sum of all probs from the dealer stage was accumulated first, then those sums accumulated at the second hand stage; and those sums accumulated at the first hand stage. This method ensures that each value accumulated will never be significantly smaller (or too much larger, for that matter) than the previous one.
Because double and even long double precision numbers only have a limited number of bits of precision (56 and 80, respectively), if you don't do it that way, then the prob of just one frequently occuring situation (with an exponent of say 2^-10) will wipe out all the accumulated results of literally millions of situations with much lower exponents in the range of say, 2^-70 to 2^-140.
Now, even when using only the unique possibilities, and using the "ways" members to help calculate the actual probs, you will still have a *huge* number of permutations.
One way to radically speed up the process is to limit the number of situations you will consider. For example, you could decide to ignore all situations where there are more than 12 cards between the two player hands. IOW, the most extreme cases would be 10 cards in one hand in two in the other; or 6 in each, etc. Since the excluded such events are so *extremely* improbable, it's pretty safe to do this. I keep my results out to 5 decimal places; and found that ignoring such extremely improbable situations has no measurable effect on the results at that level of precision.
But I do *not* limit the number of cards in the dealer's hand -- I consider *all* dealer possibilities.
I hope all this helps.
If you run into problems, please don't hesitate to contact me.