diff --git a/py/mpprint.c b/py/mpprint.c
index 82e78f62fae9b8fea0496cf0f8b8af74a819c27a..cf09f7bbe2ccd811dae302cda005b783f9140fa0 100644
--- a/py/mpprint.c
+++ b/py/mpprint.c
@@ -503,22 +503,28 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
                 chrs += mp_print_strn(print, str, prec, flags, fill, width);
                 break;
             }
-            case 'u':
-                chrs += mp_print_int(print, va_arg(args, unsigned int), 0, 10, 'a', flags, fill, width);
-                break;
-            case 'd':
-                chrs += mp_print_int(print, va_arg(args, int), 1, 10, 'a', flags, fill, width);
+            case 'd': {
+                mp_int_t val;
+                if (long_arg) {
+                    val = va_arg(args, long int);
+                } else {
+                    val = va_arg(args, int);
+                }
+                chrs += mp_print_int(print, val, 1, 10, 'a', flags, fill, width);
                 break;
+            }
+            case 'u':
             case 'x':
             case 'X': {
-                char fmt_c = *fmt - 'X' + 'A';
+                int base = 16 - ((*fmt + 1) & 6); // maps char u/x/X to base 10/16/16
+                char fmt_c = (*fmt & 0xf0) - 'P' + 'A'; // maps char u/x/X to char a/a/A
                 mp_uint_t val;
                 if (long_arg) {
                     val = va_arg(args, unsigned long int);
                 } else {
                     val = va_arg(args, unsigned int);
                 }
-                chrs += mp_print_int(print, val, 0, 16, fmt_c, flags, fill, width);
+                chrs += mp_print_int(print, val, 0, base, fmt_c, flags, fill, width);
                 break;
             }
             case 'p':