Is there a better way to size a buffer for printing integers?

后端 未结 5 612
执笔经年
执笔经年 2021-01-16 01:41

I want to create a buffer for sprintfing a integer (in this case an unsigned int). A simple and misguided approach would be:

char b         


        
5条回答
  •  被撕碎了的回忆
    2021-01-16 02:24

    Compiling different relevant comments, most notably:

    • the math question.
    • Martin R's comment that summarizes it well: “n binary digits require ceil(n*ln(2)/ln(10)) ≈ ceil(n * 0.301)”

    You have your answer:

    #define MAX_DECIMAL_SIZE(x)  ((size_t)(CHAR_BIT * sizeof(x) * 302 / 1000) + 1)
    
    char buffer[MAX_DECIMAL_SIZE(unsigned int) + 1];
    sprintf(buffer, "%u", x);
    
    /* MAX_DECIMAL_SIZE(uint8_t) => 3
     * MAX_DECIMAL_SIZE(uint16_t) => 5
     * MAX_DECIMAL_SIZE(uint32_t) => 10
     * MAX_DECIMAL_SIZE(uint64_t) => 20
     * MAX_DECIMAL_SIZE(__uint128_t) => 39 */
    

    The 302/1000 comes from ln(2)/ln(10), rounded up. You can take more digits, from 0.3010299956639812… for more precision, but that's overkill until you work with 32768-bits systems or so. Continued fractions work too (see Martin R's comment below). Either way, be careful that CHAR_BIT * sizeof(x) * is not too large and remember the result must be greater than the actual value.

    And if you really insist on octal representation, just change the multiplier to ln(2)/ln(8) (that's ⅓) and you'll have the number of octal digits required.

提交回复
热议问题