@@ -76,6 +76,32 @@ static const char *bc_count_digits(const char *str, const char *end)
76
76
return str ;
77
77
}
78
78
79
+ static inline const char * bc_skip_zero_reverse (const char * str , const char * end )
80
+ {
81
+
82
+ #ifdef __SSE2__
83
+ const __m128i c_zero_repeat = _mm_set1_epi8 ((signed char ) '0' );
84
+ while (str - sizeof (__m128i ) >= end ) {
85
+ str -= sizeof (__m128i );
86
+ __m128i bytes = _mm_loadu_si128 ((const __m128i * ) str );
87
+ bytes = _mm_cmpeq_epi8 (bytes , c_zero_repeat );
88
+
89
+ int mask = _mm_movemask_epi8 (bytes );
90
+ if (EXPECTED (mask != 0xffff )) {
91
+ str += sizeof (__m128i );
92
+ break ;
93
+ }
94
+ }
95
+ #endif
96
+
97
+ /* Exclude trailing zeros. */
98
+ while (str - 1 >= end && str [-1 ] == '0' ) {
99
+ str -- ;
100
+ }
101
+
102
+ return str ;
103
+ }
104
+
79
105
/* Assumes `num` points to NULL, i.e. does yet not hold a number. */
80
106
bool bc_str2num (bc_num * num , const char * str , const char * end , size_t scale , bool auto_scale )
81
107
{
@@ -124,9 +150,7 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, boo
124
150
}
125
151
126
152
/* Exclude trailing zeros. */
127
- while (fractional_end - 1 > decimal_point && fractional_end [-1 ] == '0' ) {
128
- fractional_end -- ;
129
- }
153
+ fractional_end = bc_skip_zero_reverse (fractional_end , fractional_ptr );
130
154
131
155
/* Move the pointer to the beginning of the fraction. */
132
156
fractional_ptr = decimal_point + 1 ;
0 commit comments