@@ -210,34 +210,94 @@ size_t Print::printNumber(unsigned long n, uint8_t base)
210
210
// prevent crash if called with base == 1
211
211
if (base < 2 ) base = 10 ;
212
212
213
- unsigned long reverse = 0 ;
214
- uint8_t digits = 0 ;
215
- char avoid_overflow = n % base;
216
-
217
- // this step and 'avoid_overflow' will make sure it stays in unsigned long range beeing able to print all 10 digits no matter what
218
- n /= base;
219
-
220
- // reverse the number and count digits
221
- while (n != 0 ) {
222
- uint8_t remainder = n % base;
223
- reverse = reverse * base + remainder ;
224
- n /= base;
225
- digits++;
226
- }
227
-
228
- // from here onwards reuse of variable 'n' to count written chars
229
- while (digits--) {
230
- char c = reverse % base;
231
- reverse /= base;
232
-
233
- c = (c < 10 ? c + ' 0' : c + ' A' - 10 );
234
- n += write (c);
213
+ // use -D ARDUINO_PRINT_NUMBER_GENERIC_ONLY when compiling to get only the generic version
214
+ #ifndef ARDUINO_PRINT_NUMBER_GENERIC_ONLY
215
+ switch (base) {
216
+ case 16 :
217
+ // optimized version for hex prints
218
+ {
219
+ uint8_t *access = (uint8_t *) &n;
220
+ uint8_t written = 0 ;
221
+ for (int8_t i=3 ; i>=0 ; i--) {
222
+ char c;
223
+ c = (access [i] & 0xf0 ) >> 4 ;
224
+ if (c != 0 || written != 0 ) {
225
+ c = (c < 10 ? c + ' 0' : c + ' A' - 10 );
226
+ written += write (c);
227
+ } // else: skip leading zeros
228
+ c = access [i] & 0x0f ;
229
+ if (c != 0 || written != 0 ) {
230
+ // skip leading zeros
231
+ c = (c < 10 ? c + ' 0' : c + ' A' - 10 );
232
+ written += write (c);
233
+ } // else: skip leading zeros
234
+ }
235
+ return written;
236
+ }
237
+ case 2 :
238
+ // optimized version for binary prints
239
+ {
240
+ uint8_t *access = (uint8_t *) &n;
241
+ uint8_t written = 0 ;
242
+ for (int8_t i=3 ; i>=0 ; i--) {
243
+ if (access [i] == 0 && written == 0 ) {
244
+ // skip leading zeros
245
+ continue ;
246
+ }
247
+ for (int8_t j=7 ; j>=0 ; j--) {
248
+ char c;
249
+ if (j == 0 ) {
250
+ // avoid shift by 0 - undefined
251
+ c = (access [i] & 0x01 );
252
+ } else {
253
+ c = (access [i] & 1 <<j) >> j;
254
+ }
255
+ if (c == 0 && written == 0 ) {
256
+ // skip leading zeros
257
+ continue ;
258
+ }
259
+ c = (c < 10 ? c + ' 0' : c + ' A' - 10 );
260
+ written += write (c);
261
+ }
262
+ }
263
+ return written;
264
+ }
265
+ default :
266
+ // the generic implementation
267
+ #endif
268
+ {
269
+ unsigned long reverse = 0 ;
270
+ uint8_t digits = 0 ;
271
+ char avoid_overflow = n % base;
272
+
273
+ // this step and 'avoid_overflow' will make sure it stays in unsigned long range beeing able to print all 10 digits no matter what
274
+ n /= base;
275
+
276
+ // reverse the number and count digits
277
+ while (n != 0 ) {
278
+ uint8_t remainder = n % base;
279
+ reverse = reverse * base + remainder ;
280
+ n /= base;
281
+ digits++;
282
+ }
283
+
284
+ // from here onwards reuse of variable 'n' to count written chars
285
+ while (digits--) {
286
+ char c = reverse % base;
287
+ reverse /= base;
288
+
289
+ c = (c < 10 ? c + ' 0' : c + ' A' - 10 );
290
+ n += write (c);
291
+ }
292
+
293
+ avoid_overflow = (avoid_overflow < 10 ? avoid_overflow + ' 0' : avoid_overflow + ' A' - 10 );
294
+ n += write (avoid_overflow);
295
+
296
+ return n;
297
+ }
298
+ #ifndef ARDUINO_PRINT_NUMBER_GENERIC_ONLY
235
299
}
236
-
237
- avoid_overflow = (avoid_overflow < 10 ? avoid_overflow + ' 0' : avoid_overflow + ' A' - 10 );
238
- n += write (avoid_overflow);
239
-
240
- return n;
300
+ #endif
241
301
}
242
302
243
303
size_t Print::printFloat (double number, uint8_t digits)
0 commit comments