Как улучшить определение размера буфера для печати различных целочисленных типов?

При преобразовании целого числа в текст, как правило, я создаюбольшой буфер для использования сsprintf() провести любой потенциальный результат.

char BigBuffer[50];
sprintf(BugBuffer, "%d", SomeInt);

Я хотел бы более экономичный и, конечно, портативный, поэтому вместо50, нашел альтернативу:
(sizeof(integer_type)*CHAR_BIT*0.302) + 3

// 0.0302 about log10(2)
#define USHORT_DECIMAL_BUFN ((size_t) (sizeof(unsigned short)*CHAR_BIT*0.302) + 3)
#define INT_DECIMAL_BUFN    ((size_t) (sizeof(int)           *CHAR_BIT*0.302) + 3)
#define INTMAX_DECIMAL_BUFN ((size_t) (sizeof(intmax_t)      *CHAR_BIT*0.302) + 3)

int main() {
    char usbuffer[USHORT_DECIMAL_BUFN];
    sprintf(usbuffer, "%hu", USHRT_MAX);
    printf("Size:%zu Len:%zu %s\n", sizeof(usbuffer), strlen(usbuffer), usbuffer);

    char ibuffer[INT_DECIMAL_BUFN];
    sprintf(ibuffer, "%d", INT_MIN);
    printf("Size:%zu Len:%zu %s\n", sizeof(ibuffer), strlen(ibuffer), ibuffer);

    char imbuffer[INTMAX_DECIMAL_BUFN];
    sprintf(imbuffer, "%" PRIdMAX, INTMAX_MIN);
    printf("Size:%zu Len:%zu %s\n", sizeof(imbuffer), strlen(imbuffer), imbuffer);
    return 0;
}

Size:7 Len:5 65535
Size:12 Len:11 -2147483648
Size:22 Len:20 -9223372036854775808

Так чтовопросов находятся:
1 Есть ли проблема с альтернативным уравнением?
2 Какое лучшее решение? - поскольку эта альтернатива немного расточительна и выглядит слишком сложной.

[РедактироватьОтвет]

Ответы обеспечивают 3 продуманных подхода:
1 Используйте буфер [максимальный размер для типа] (Ответ выбран)
2 asprintf()
3 snprintf()

1 Максимальный размер буфера времени компиляции с использованием уравнения(sizeof(integer_type)*CHAR_BIT*0.302) + 3 не был сломан или улучшен. Влияние<locale.h> был исследован в соответствии с предложением @paddy, и никакие настройки локали не влияли на целочисленные преобразования%d %x %u %i, Было обнаружено, что в уравнение можно внести небольшие улучшения, если известно, что тип подписан или не подписан (ниже). Предупреждение @paddy о «более консервативном» - это хороший совет.

2 asprintf() действительно хорошее универсальное решение, но не портативное. Может быть, в пост-С11?

3 snprintf()хотя и является стандартным, имеет известные проблемы реализации, когда поставляемый буфер слишком мал. Это подразумевает вызов его с буфером большего размера, а затем генерирование буфера правильного размера. @jxh предложил потокобезопасный глобальный буфер с нуля, чтобы сформировать ответ с локальным буфером правильного размера. Этот новый подход заслуживает рассмотрения, которое я могу использовать, но первоначальный вопрос был сосредоточен на определении доs(n)printf() назвать консервативный размер буфера.

signed ((sizeof(integer_type)*CHAR_BIT-1)*0.302) + 3
unsigned (sizeof(integer_type)*CHAR_BIT*0.302) + 2
*28/93 может быть использован вместо*0.302.

Ответы на вопрос(4)

Ваш ответ на вопрос