Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 870432e

Browse files
improved on base 2 and base 16 print number implementations
added compile flag to disable those additional optimized implementations
1 parent e2f54b1 commit 870432e

File tree

1 file changed

+87
-27
lines changed

1 file changed

+87
-27
lines changed

‎cores/arduino/Print.cpp‎

Lines changed: 87 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -210,34 +210,94 @@ size_t Print::printNumber(unsigned long n, uint8_t base)
210210
// prevent crash if called with base == 1
211211
if (base < 2) base = 10;
212212

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
235299
}
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
241301
}
242302

243303
size_t Print::printFloat(double number, uint8_t digits)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /