当我阅读git的源代码时,我对此宏感到困惑。
/* Approximation of the length of the decimal representation of this type. */
#define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
但是当我尝试计算一个类型的十进制表示长度的近似值时,我认为答案是
((int)(sizeof(x) * 8 * ln2 ) + 1)
可写为
((int)(sizeof(x) * 2.41 ) + 1)
你能告诉我为什么git用“(sizeof(x)* 2.56 + 0.5)”而不是“(sizeof(x)* 2.41)”来计算长度吗?
非常感谢。
答案 0 :(得分:3)
似乎是一次烘烤的机会!以下是我从四种不同数字大小得到的结果:
A = (sizeof(x) * 2.56 + 0.5) + 1
B = (sizeof(x) * 2.41) + 1
C = (sizeof(x) * 2.41 + 1.65)
strlen A B C Number (bytes)
4 4 3 4 -127 (1)
6 6 5 6 -32767 (2)
11 11 10 11 -2147483647 (4)
20 21 20 20 -9223372036854775807 (8)
感谢用户3386109 。所有这些方案都试图估计最大可能长度,而不是实际长度(即他们不关心x'包含的值)。下面是我用来生成上表的代码。我没有在我的系统中添加long long
,它的大小与long
相同。
#include <stdio.h>
#include <string.h>
#define decimal_length1(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
#define decimal_length2(x) ((int)(sizeof(x) * 2.41) + 1)
#define decimal_length3(x) ((int)(sizeof(x) * 2.41 + 1.65))
int main() {
char buffer[1024];
char a = -127;
short b = -32767;
int c = -2147483647;
long int d = -9223372036854775807L;
printf("A = (sizeof(x) * 2.56 + 0.5) + 1\n");
printf("B = (sizeof(x) * 2.41) + 1\n");
printf("C = (sizeof(x) * 2.41 + 1.65)\n\n");
printf("strlen\tA\tB\tC\tNumber (bytes)\n\n");
sprintf(buffer, "%hhd", a);
printf("%lu\t%d\t%d\t%d\t%s (%lu)\n", strlen(buffer), decimal_length1(a), decimal_length2(a), decimal_length3(a), buffer, sizeof(a));
sprintf(buffer, "%hd", b);
printf("%lu\t%d\t%d\t%d\t%s (%lu)\n", strlen(buffer), decimal_length1(b), decimal_length2(b), decimal_length3(b), buffer, sizeof(b));
sprintf(buffer, "%d", c);
printf("%lu\t%d\t%d\t%d\t%s (%lu)\n", strlen(buffer), decimal_length1(c), decimal_length2(c), decimal_length3(c), buffer, sizeof(c));
sprintf(buffer, "%ld", d);
printf("%lu\t%d\t%d\t%d\t%s (%lu)\n", strlen(buffer), decimal_length1(d), decimal_length2(d), decimal_length3(d), buffer, sizeof(d));
return 0;
}