diff --git a/libc/printf.cc b/libc/printf.cc
index 238cecdca5706b624ce2fe20221c4c2e32a88149..4251d37be4f0a596d6b9a1a63aa25e5ebe7adef2 100644
--- a/libc/printf.cc
+++ b/libc/printf.cc
@@ -255,12 +255,16 @@ std::string strprintf(const char* fmt, va_list ap)
             auto arg = make_int_arg(pos, int_size());
             frags.push_back([=] {
                 std::string ret;
-                auto val = arg->val;
+                bool negative = arg->val < 0;
+                uintmax_t val = std::abs(arg->val);
                 while (val) {
                     ret.push_back('0' + val % 10);
                     val /= 10;
                 };
-                fill_right_to(ret, '0', precision_fn());
+                fill_right_to(ret, '0', precision_fn() - negative);
+                if (negative) {
+                    ret.push_back('-');
+                }
                 fill_right_to(ret, ' ', width_fn());
                 std::reverse(ret.begin(), ret.end());
                 return ret;