This code #include <stdio.h> int main(void){ (void)printf("%.0a\n", 1.); (void)printf("%.0a\n", 2.); (void)printf("%.0a\n", 4.); (void)printf("%.0a\n", 8.); (void)printf("%.0a\n", 16.); (void)printf("%.0a\n", 3.); (void)printf("%.0a\n", 6.); (void)printf("%.0a\n", 12.); (void)printf("%.0a\n", 23.); (void)printf("%.0a\n", 24.); (void)printf("%.0a\n", 25.); return 0; } shows that printf uses both 1 bit and 2 bits for the integer part before the 'p' (which seems inconsistent). My guess is it depends upon rounding up.
The only requirement is that there is a single nonzero digit before the hexadecimal point.