浮点数和双打的最长可能的 %a 字符串?

问题描述 投票:0回答:2

%a
说明符与
printf
系列函数一起使用时,浮点数和双精度数的最长可能字符串是多少?

假设 float 和 double 是 IEEE-754 32 位和 64 位浮点数。

更具体地说,对于以下函数,

buf
需要多大才能使
buf
不会溢出(注意
sprintf
也会写一个空终止符):

#include <stdio.h>

void StringFromFloat(char *buf, float f) {
    sprintf(buf, "%a", f);
}

void StringFromDouble(char *buf, double d) {
    sprintf(buf, "%a", d);
}

我假设

%A
的最大长度没有差异。

c floating-point printf ieee-754
2个回答
0
投票
int main() {
    int c;
    printf("%a%n\n", -M_PI, &c);
    printf("%d\n", c+1);
    printf("%a%n\n", -DBL_MAX, &c);
    printf("%d\n", c+1);
    printf("%a%n\n", -DBL_MIN, &c);
    printf("%d\n", c+1);
}

发射

-0x1.921fb54442d18p+1
22
-0x1.fffffffffffffp+1023
25
-0x1p-1022
11

https://coliru.stacked-crooked.com/a/9c8e5f7a059b66a5

如果我们假设格式是标准的,并且双字节是 IEEE-754 64 位,那么答案似乎是 26 的长度(包括尾随的空值)

IEEE-754 64 位类型使用一个符号位(1 个字符)、一个 52 位尾数(13 个十六进制字符)和一个 11 位指数(5 个十六进制字符)。这符合我们上面的结果(

-
fffffffffffff
+1023
),这意味着其他 6 个字节是〜标准格式(
0x1.
p
'\0'


0
投票

最长的字符串是什么

通常这是 length 所需的缓冲区 size 比长度多 1.


"%a"
有各种实现定义的细节。

合理估计:总和:

  • 最长的有效数字长度,可能是 -1.xxx...xxx 的形式,其中 x 是十六进制数字。假设

    FLT_RADIX==2
    1 /* sign */ + 2 /* 0x */ + 1 /* lead digit */ + 1 /* . */ + roundup((xxx_MANT_DIG-1)/4)
    .

  • 最长的指数,它是值

    xxx_TRUE_MIN
    1 /* p */ + 1 /* sign */ + roundup(log2(-xxx_MIN_EXP + xxx_MANT_DIG))
    的 2 的十进制次方。

通常通过

snprinf(NULL, 0, "%a", -xxx_TRUE_MIN)
找到最大长度,但这并不总是正确的。


对于常见的

double

significand length: `1 + 2 + 1 + 1 + ru((53-1)/4)` --> 18

exponent length: `1 + 1 + ru(log10(- -1021 + 53))` --> 6

sum: 24

对于常见的

float

significand length: `1 + 2 + 1 + 1 + ru((24-1)/4)` --> 11

exponent length: `1 + 1 + ru(log10(- -125 + 24))` --> 5

sum: 16

考虑 NAN 的有效载荷可能以某种有趣的方式格式化,可能超过上述总和。我还没有遇到过。

© www.soinside.com 2019 - 2024. All rights reserved.