@@ -44,211 +44,231 @@ typedef uint_fast64_t u64_t;
44
44
#define u32 (x ) ((u32_t)(x))
45
45
#define u64 (x ) ((u64_t)(x))
46
46
47
- struct pair
47
+ struct digit_pair
48
48
{
49
49
char dd [2 ];
50
50
};
51
51
52
- #define cast_to_pair_ptr (b ) ((struct pair*)(void*)(b))
52
+ static const struct digit_pair * digits_dd = (struct digit_pair * )(
53
+ "00" "01" "02" "03" "04" "05" "06" "07" "08" "09"
54
+ "10" "11" "12" "13" "14" "15" "16" "17" "18" "19"
55
+ "20" "21" "22" "23" "24" "25" "26" "27" "28" "29"
56
+ "30" "31" "32" "33" "34" "35" "36" "37" "38" "39"
57
+ "40" "41" "42" "43" "44" "45" "46" "47" "48" "49"
58
+ "50" "51" "52" "53" "54" "55" "56" "57" "58" "59"
59
+ "60" "61" "62" "63" "64" "65" "66" "67" "68" "69"
60
+ "70" "71" "72" "73" "74" "75" "76" "77" "78" "79"
61
+ "80" "81" "82" "83" "84" "85" "86" "87" "88" "89"
62
+ "90" "91" "92" "93" "94" "95" "96" "97" "98" "99"
63
+ );
53
64
54
- static struct pair digits_dd [100 ] =
55
- {
56
- { '0' , '0' }, { '0' , '1' }, { '0' , '2' }, { '0' , '3' }, { '0' , '4' }, { '0' , '5' }, { '0' , '6' }, { '0' , '7' }, { '0' , '8' }, { '0' , '9' },
57
- { '1' , '0' }, { '1' , '1' }, { '1' , '2' }, { '1' , '3' }, { '1' , '4' }, { '1' , '5' }, { '1' , '6' }, { '1' , '7' }, { '1' , '8' }, { '1' , '9' },
58
- { '2' , '0' }, { '2' , '1' }, { '2' , '2' }, { '2' , '3' }, { '2' , '4' }, { '2' , '5' }, { '2' , '6' }, { '2' , '7' }, { '2' , '8' }, { '2' , '9' },
59
- { '3' , '0' }, { '3' , '1' }, { '3' , '2' }, { '3' , '3' }, { '3' , '4' }, { '3' , '5' }, { '3' , '6' }, { '3' , '7' }, { '3' , '8' }, { '3' , '9' },
60
- { '4' , '0' }, { '4' , '1' }, { '4' , '2' }, { '4' , '3' }, { '4' , '4' }, { '4' , '5' }, { '4' , '6' }, { '4' , '7' }, { '4' , '8' }, { '4' , '9' },
61
- { '5' , '0' }, { '5' , '1' }, { '5' , '2' }, { '5' , '3' }, { '5' , '4' }, { '5' , '5' }, { '5' , '6' }, { '5' , '7' }, { '5' , '8' }, { '5' , '9' },
62
- { '6' , '0' }, { '6' , '1' }, { '6' , '2' }, { '6' , '3' }, { '6' , '4' }, { '6' , '5' }, { '6' , '6' }, { '6' , '7' }, { '6' , '8' }, { '6' , '9' },
63
- { '7' , '0' }, { '7' , '1' }, { '7' , '2' }, { '7' , '3' }, { '7' , '4' }, { '7' , '5' }, { '7' , '6' }, { '7' , '7' }, { '7' , '8' }, { '7' , '9' },
64
- { '8' , '0' }, { '8' , '1' }, { '8' , '2' }, { '8' , '3' }, { '8' , '4' }, { '8' , '5' }, { '8' , '6' }, { '8' , '7' }, { '8' , '8' }, { '8' , '9' },
65
- { '9' , '0' }, { '9' , '1' }, { '9' , '2' }, { '9' , '3' }, { '9' , '4' }, { '9' , '5' }, { '9' , '6' }, { '9' , '7' }, { '9' , '8' }, { '9' , '9' },
66
- };
67
-
68
- #define NUL 'x'
69
-
70
- static struct pair digits_fd [100 ] =
71
- {
72
- { '0' , NUL }, { '1' , NUL }, { '2' , NUL }, { '3' , NUL }, { '4' , NUL }, { '5' , NUL }, { '6' , NUL }, { '7' , NUL }, { '8' , NUL }, { '9' , NUL },
73
- { '1' , '0' }, { '1' , '1' }, { '1' , '2' }, { '1' , '3' }, { '1' , '4' }, { '1' , '5' }, { '1' , '6' }, { '1' , '7' }, { '1' , '8' }, { '1' , '9' },
74
- { '2' , '0' }, { '2' , '1' }, { '2' , '2' }, { '2' , '3' }, { '2' , '4' }, { '2' , '5' }, { '2' , '6' }, { '2' , '7' }, { '2' , '8' }, { '2' , '9' },
75
- { '3' , '0' }, { '3' , '1' }, { '3' , '2' }, { '3' , '3' }, { '3' , '4' }, { '3' , '5' }, { '3' , '6' }, { '3' , '7' }, { '3' , '8' }, { '3' , '9' },
76
- { '4' , '0' }, { '4' , '1' }, { '4' , '2' }, { '4' , '3' }, { '4' , '4' }, { '4' , '5' }, { '4' , '6' }, { '4' , '7' }, { '4' , '8' }, { '4' , '9' },
77
- { '5' , '0' }, { '5' , '1' }, { '5' , '2' }, { '5' , '3' }, { '5' , '4' }, { '5' , '5' }, { '5' , '6' }, { '5' , '7' }, { '5' , '8' }, { '5' , '9' },
78
- { '6' , '0' }, { '6' , '1' }, { '6' , '2' }, { '6' , '3' }, { '6' , '4' }, { '6' , '5' }, { '6' , '6' }, { '6' , '7' }, { '6' , '8' }, { '6' , '9' },
79
- { '7' , '0' }, { '7' , '1' }, { '7' , '2' }, { '7' , '3' }, { '7' , '4' }, { '7' , '5' }, { '7' , '6' }, { '7' , '7' }, { '7' , '8' }, { '7' , '9' },
80
- { '8' , '0' }, { '8' , '1' }, { '8' , '2' }, { '8' , '3' }, { '8' , '4' }, { '8' , '5' }, { '8' , '6' }, { '8' , '7' }, { '8' , '8' }, { '8' , '9' },
81
- { '9' , '0' }, { '9' , '1' }, { '9' , '2' }, { '9' , '3' }, { '9' , '4' }, { '9' , '5' }, { '9' , '6' }, { '9' , '7' }, { '9' , '8' }, { '9' , '9' },
82
- };
65
+ static const struct digit_pair * digits_fd = (struct digit_pair * )(
66
+ "0_" "1_" "2_" "3_" "4_" "5_" "6_" "7_" "8_" "9_"
67
+ "10" "11" "12" "13" "14" "15" "16" "17" "18" "19"
68
+ "20" "21" "22" "23" "24" "25" "26" "27" "28" "29"
69
+ "30" "31" "32" "33" "34" "35" "36" "37" "38" "39"
70
+ "40" "41" "42" "43" "44" "45" "46" "47" "48" "49"
71
+ "50" "51" "52" "53" "54" "55" "56" "57" "58" "59"
72
+ "60" "61" "62" "63" "64" "65" "66" "67" "68" "69"
73
+ "70" "71" "72" "73" "74" "75" "76" "77" "78" "79"
74
+ "80" "81" "82" "83" "84" "85" "86" "87" "88" "89"
75
+ "90" "91" "92" "93" "94" "95" "96" "97" "98" "99"
76
+ );
83
77
84
- #undef NUL
78
+ static const u64_t mask24 = (u64 (1 ) << 24 ) - 1 ;
79
+ static const u64_t mask32 = (u64 (1 ) << 32 ) - 1 ;
80
+ static const u64_t mask57 = (u64 (1 ) << 57 ) - 1 ;
85
81
86
- static u64_t mask24 = (u64 (1 ) << 24 ) - 1 ;
87
- static u64_t mask32 = (u64 (1 ) << 32 ) - 1 ;
88
- static u64_t mask57 = (u64 (1 ) << 57 ) - 1 ;
82
+ #define COPY (buffer , digits ) memcpy(buffer, &(digits), sizeof(struct digit_pair))
89
83
90
- static
91
- char * to_text_from_ulong (char * b , u64_t n ) {
92
- if ( n < u32 ( 1e2 ))
93
- {
94
- * cast_to_pair_ptr ( b ) = digits_fd [n ];
84
+ static char *
85
+ jeaiii_ultoa (char * b , u64_t n )
86
+ {
87
+ if ( n < u32 ( 1e2 )) {
88
+ COPY ( b , digits_fd [n ]) ;
95
89
return n < 10 ? b + 1 : b + 2 ;
96
90
}
97
- if (n < u32 (1e6 ))
98
- {
99
- if (n < u32 (1e4 ))
100
- {
91
+
92
+ if (n < u32 (1e6 )) {
93
+ if (n < u32 (1e4 )) {
101
94
u32_t f0 = u32 (10 * (1 << 24 ) / 1e3 + 1 ) * n ;
102
- * cast_to_pair_ptr (b ) = digits_fd [f0 >> 24 ];
95
+ COPY (b , digits_fd [f0 >> 24 ]);
96
+
103
97
b -= n < u32 (1e3 );
104
98
u32_t f2 = (f0 & mask24 ) * 100 ;
105
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 24 ];
99
+ COPY (b + 2 , digits_dd [f2 >> 24 ]);
100
+
106
101
return b + 4 ;
107
102
}
103
+
108
104
u64_t f0 = u64 (10 * (1ull << 32ull )/ 1e5 + 1 ) * n ;
109
- * cast_to_pair_ptr (b ) = digits_fd [f0 >> 32 ];
105
+ COPY (b , digits_fd [f0 >> 32 ]);
106
+
110
107
b -= n < u32 (1e5 );
111
108
u64_t f2 = (f0 & mask32 ) * 100 ;
112
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 32 ];
109
+ COPY (b + 2 , digits_dd [f2 >> 32 ]);
110
+
113
111
u64_t f4 = (f2 & mask32 ) * 100 ;
114
- * cast_to_pair_ptr (b + 4 ) = digits_dd [f4 >> 32 ];
112
+ COPY (b + 4 , digits_dd [f4 >> 32 ]) ;
115
113
return b + 6 ;
116
114
}
117
- if (n < u64 (1ull << 32ull ))
118
- {
119
- if (n < u32 (1e8 ))
120
- {
115
+
116
+ if (n < u64 (1ull << 32ull )) {
117
+ if (n < u32 (1e8 )) {
121
118
u64_t f0 = u64 (10 * (1ull << 48ull ) / 1e7 + 1 ) * n >> 16 ;
122
- * cast_to_pair_ptr (b ) = digits_fd [f0 >> 32 ];
119
+ COPY (b , digits_fd [f0 >> 32 ]);
120
+
123
121
b -= n < u32 (1e7 );
124
122
u64_t f2 = (f0 & mask32 ) * 100 ;
125
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 32 ];
123
+ COPY (b + 2 , digits_dd [f2 >> 32 ]);
124
+
126
125
u64_t f4 = (f2 & mask32 ) * 100 ;
127
- * cast_to_pair_ptr (b + 4 ) = digits_dd [f4 >> 32 ];
126
+ COPY (b + 4 , digits_dd [f4 >> 32 ]);
127
+
128
128
u64_t f6 = (f4 & mask32 ) * 100 ;
129
- * cast_to_pair_ptr (b + 6 ) = digits_dd [f6 >> 32 ];
129
+ COPY (b + 6 , digits_dd [f6 >> 32 ]);
130
+
130
131
return b + 8 ;
131
132
}
133
+
132
134
u64_t f0 = u64 (10 * (1ull << 57ull ) / 1e9 + 1 ) * n ;
133
- * cast_to_pair_ptr (b ) = digits_fd [f0 >> 57 ];
135
+ COPY (b , digits_fd [f0 >> 57 ]);
136
+
134
137
b -= n < u32 (1e9 );
135
138
u64_t f2 = (f0 & mask57 ) * 100 ;
136
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 57 ];
139
+ COPY (b + 2 , digits_dd [f2 >> 57 ]);
140
+
137
141
u64_t f4 = (f2 & mask57 ) * 100 ;
138
- * cast_to_pair_ptr (b + 4 ) = digits_dd [f4 >> 57 ];
142
+ COPY (b + 4 , digits_dd [f4 >> 57 ]);
143
+
139
144
u64_t f6 = (f4 & mask57 ) * 100 ;
140
- * cast_to_pair_ptr (b + 6 ) = digits_dd [f6 >> 57 ];
145
+ COPY (b + 6 , digits_dd [f6 >> 57 ]);
146
+
141
147
u64_t f8 = (f6 & mask57 ) * 100 ;
142
- * cast_to_pair_ptr (b + 8 ) = digits_dd [f8 >> 57 ];
148
+ COPY (b + 8 , digits_dd [f8 >> 57 ]);
149
+
143
150
return b + 10 ;
144
151
}
145
152
146
153
// if we get here U must be u64 but some compilers don't know that, so reassign n to a u64 to avoid warnings
147
154
u32_t z = n % u32 (1e8 );
148
155
u64_t u = n / u32 (1e8 );
149
156
150
- if (u < u32 (1e2 ))
151
- {
157
+ if (u < u32 (1e2 )) {
152
158
// u can't be 1 digit (if u < 10 it would have been handled above as a 9 digit 32bit number)
153
- * cast_to_pair_ptr ( b ) = digits_dd [u ];
159
+ COPY ( b , digits_dd [u ]) ;
154
160
b += 2 ;
155
161
}
156
- else if (u < u32 (1e6 ))
157
- {
158
- if (u < u32 (1e4 ))
159
- {
162
+ else if (u < u32 (1e6 )) {
163
+ if (u < u32 (1e4 )) {
160
164
u32_t f0 = u32 (10 * (1 << 24 ) / 1e3 + 1 ) * u ;
161
- * cast_to_pair_ptr (b ) = digits_fd [f0 >> 24 ];
165
+ COPY (b , digits_fd [f0 >> 24 ]);
166
+
162
167
b -= u < u32 (1e3 );
163
168
u32_t f2 = (f0 & mask24 ) * 100 ;
164
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 24 ];
169
+ COPY (b + 2 , digits_dd [f2 >> 24 ]) ;
165
170
b += 4 ;
166
171
}
167
- else
168
- {
172
+ else {
169
173
u64_t f0 = u64 (10 * (1ull << 32ull ) / 1e5 + 1 ) * u ;
170
- * cast_to_pair_ptr (b ) = digits_fd [f0 >> 32 ];
174
+ COPY (b , digits_fd [f0 >> 32 ]);
175
+
171
176
b -= u < u32 (1e5 );
172
177
u64_t f2 = (f0 & mask32 ) * 100 ;
173
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 32 ];
178
+ COPY (b + 2 , digits_dd [f2 >> 32 ]);
179
+
174
180
u64_t f4 = (f2 & mask32 ) * 100 ;
175
- * cast_to_pair_ptr (b + 4 ) = digits_dd [f4 >> 32 ];
181
+ COPY (b + 4 , digits_dd [f4 >> 32 ]) ;
176
182
b += 6 ;
177
183
}
178
184
}
179
- else if (u < u32 (1e8 ))
180
- {
185
+ else if (u < u32 (1e8 )) {
181
186
u64_t f0 = u64 (10 * (1ull << 48ull ) / 1e7 + 1 ) * u >> 16 ;
182
- * cast_to_pair_ptr (b ) = digits_fd [f0 >> 32 ];
187
+ COPY (b , digits_fd [f0 >> 32 ]);
188
+
183
189
b -= u < u32 (1e7 );
184
190
u64_t f2 = (f0 & mask32 ) * 100 ;
185
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 32 ];
191
+ COPY (b + 2 , digits_dd [f2 >> 32 ]);
192
+
186
193
u64_t f4 = (f2 & mask32 ) * 100 ;
187
- * cast_to_pair_ptr (b + 4 ) = digits_dd [f4 >> 32 ];
194
+ COPY (b + 4 , digits_dd [f4 >> 32 ]);
195
+
188
196
u64_t f6 = (f4 & mask32 ) * 100 ;
189
- * cast_to_pair_ptr (b + 6 ) = digits_dd [f6 >> 32 ];
197
+ COPY (b + 6 , digits_dd [f6 >> 32 ]);
198
+
190
199
b += 8 ;
191
200
}
192
- else if (u < u64 (1ull << 32ull ))
193
- {
201
+ else if (u < u64 (1ull << 32ull )) {
194
202
u64_t f0 = u64 (10 * (1ull << 57ull ) / 1e9 + 1 ) * u ;
195
- * cast_to_pair_ptr (b ) = digits_fd [f0 >> 57 ];
203
+ COPY (b , digits_fd [f0 >> 57 ]);
204
+
196
205
b -= u < u32 (1e9 );
197
206
u64_t f2 = (f0 & mask57 ) * 100 ;
198
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 57 ];
207
+ COPY (b + 2 , digits_dd [f2 >> 57 ]);
208
+
199
209
u64_t f4 = (f2 & mask57 ) * 100 ;
200
- * cast_to_pair_ptr (b + 4 ) = digits_dd [f4 >> 57 ];
210
+ COPY (b + 4 , digits_dd [f4 >> 57 ]);
211
+
201
212
u64_t f6 = (f4 & mask57 ) * 100 ;
202
- * cast_to_pair_ptr (b + 6 ) = digits_dd [f6 >> 57 ];
213
+ COPY (b + 6 , digits_dd [f6 >> 57 ]);
214
+
203
215
u64_t f8 = (f6 & mask57 ) * 100 ;
204
- * cast_to_pair_ptr (b + 8 ) = digits_dd [f8 >> 57 ];
216
+ COPY (b + 8 , digits_dd [f8 >> 57 ]) ;
205
217
b += 10 ;
206
218
}
207
- else
208
- {
219
+ else {
209
220
u32_t y = u % u32 (1e8 );
210
221
u /= u32 (1e8 );
211
222
212
223
// u is 2, 3, or 4 digits (if u < 10 it would have been handled above)
213
- if (u < u32 (1e2 ))
214
- {
215
- * cast_to_pair_ptr (b ) = digits_dd [u ];
224
+ if (u < u32 (1e2 )) {
225
+ COPY (b , digits_dd [u ]);
216
226
b += 2 ;
217
227
}
218
- else
219
- {
228
+ else {
220
229
u32_t f0 = u32 (10 * (1 << 24 ) / 1e3 + 1 ) * u ;
221
- * cast_to_pair_ptr (b ) = digits_fd [f0 >> 24 ];
230
+ COPY (b , digits_fd [f0 >> 24 ]);
231
+
222
232
b -= u < u32 (1e3 );
223
233
u32_t f2 = (f0 & mask24 ) * 100 ;
224
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 24 ];
234
+ COPY (b + 2 , digits_dd [f2 >> 24 ]);
235
+
225
236
b += 4 ;
226
237
}
227
238
// do 8 digits
228
239
u64_t f0 = (u64 ((1ull << 48ull ) / 1e6 + 1 ) * y >> 16 ) + 1 ;
229
- * cast_to_pair_ptr (b ) = digits_dd [f0 >> 32 ];
240
+ COPY (b , digits_dd [f0 >> 32 ]);
241
+
230
242
u64_t f2 = (f0 & mask32 ) * 100 ;
231
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 32 ];
243
+ COPY (b + 2 , digits_dd [f2 >> 32 ]);
244
+
232
245
u64_t f4 = (f2 & mask32 ) * 100 ;
233
- * cast_to_pair_ptr (b + 4 ) = digits_dd [f4 >> 32 ];
246
+ COPY (b + 4 , digits_dd [f4 >> 32 ]);
247
+
234
248
u64_t f6 = (f4 & mask32 ) * 100 ;
235
- * cast_to_pair_ptr (b + 6 ) = digits_dd [f6 >> 32 ];
249
+ COPY (b + 6 , digits_dd [f6 >> 32 ]) ;
236
250
b += 8 ;
237
251
}
252
+
238
253
// do 8 digits
239
254
u64_t f0 = (u64 ((1ull << 48ull ) / 1e6 + 1 ) * z >> 16 ) + 1 ;
240
- * cast_to_pair_ptr (b ) = digits_dd [f0 >> 32 ];
255
+ COPY (b , digits_dd [f0 >> 32 ]);
256
+
241
257
u64_t f2 = (f0 & mask32 ) * 100 ;
242
- * cast_to_pair_ptr (b + 2 ) = digits_dd [f2 >> 32 ];
258
+ COPY (b + 2 , digits_dd [f2 >> 32 ]);
259
+
243
260
u64_t f4 = (f2 & mask32 ) * 100 ;
244
- * cast_to_pair_ptr (b + 4 ) = digits_dd [f4 >> 32 ];
261
+ COPY (b + 4 , digits_dd [f4 >> 32 ]);
262
+
245
263
u64_t f6 = (f4 & mask32 ) * 100 ;
246
- * cast_to_pair_ptr (b + 6 ) = digits_dd [f6 >> 32 ];
264
+ COPY (b + 6 , digits_dd [f6 >> 32 ]);
265
+
247
266
return b + 8 ;
248
267
}
249
268
250
269
#undef u32
251
270
#undef u64
271
+ #undef COPY
252
272
253
273
#pragma clang diagnostic pop
254
274
#pragma GCC diagnostic pop
0 commit comments