11#include " zoo/swar/SWAR.h"
22#include " zoo/swar/associative_iteration.h"
33
4- #include < benchmark/benchmark.h>
5-
64#include < stdint.h>
75#include < string.h>
86#include < stdlib.h>
97
108// Copied from Daniel Lemire's GitHub at
9+ // https://lemire.me/blog/2018/10/03/quickly-parsing-eight-digits/
1110// https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/ddb082981228f7256e9a4dbbf56fd4a335d78e30/2018/10/03/eightchartoi.c#L26C1-L34C2
1211
13- uint32_t parse_eight_digits_swar (const unsigned char *chars) {
12+ uint32_t parse_eight_digits_swar (const char *chars) {
1413 uint64_t val;
1514 memcpy (&val, chars, 8 );
1615 val = val - 0x3030303030303030 ;
@@ -22,8 +21,6 @@ uint32_t parse_eight_digits_swar(const unsigned char *chars) {
2221
2322// Note: eight digits can represent from 0 to (10^9) - 1, the logarithm base 2
2423// of 10^9 is slightly less than 30, thus, only 30 bits are needed.
25- template <typename > struct Trick ;
26-
2724auto lemire_as_zoo_swar (const char *chars) {
2825 uint64_t bytes;
2926 memcpy (&bytes, chars, 8 );
@@ -40,12 +37,15 @@ auto lemire_as_zoo_swar(const char *chars) {
4037 * BASE256 10*B 10*C 10*D 10*E 10*F 10*G 10*H 0
4138 * --------------------------------------
4239 * BASE256 A+10B ....................... G+10H H
40+ * See that the odd-digits (base256) contain 10*odd + even
41+ * Then, we can use base(2^16) digits, and base(2^32) to
42+ * calculate the conversion for the digits in 100s and 10,000s
4343 */
4444 auto by11base256 = convertedToIntegers.multiply (256 *10 + 1 );
4545 auto bytePairs = zoo::swar::doublePrecision (by11base256).odd ;
4646 static_assert (std::is_same_v<decltype (bytePairs), zoo::swar::SWAR<16 , uint64_t >>);
47- auto by101base2to16 = bytePairs.multiply (1 + 100 << 16 );
47+ auto by101base2to16 = bytePairs.multiply (1 + ( 100 << 16 ) );
4848 auto byteQuads = zoo::swar::doublePrecision (by101base2to16).odd ;
49- auto by10001base2to32 = zoo::swar::doublePrecision (by101base2to16). odd ;
50- return uint32_t (zoo::swar::doublePrecision ( by10001base2to32). odd . value ());
49+ auto by10001base2to32 = byteQuads. multiply ( 1 + ( 10000ull << 32 )) ;
50+ return uint32_t (by10001base2to32. value () >> 32 );
5151}
0 commit comments