代表任何双精度值的最大字符长度是多少?

当我将无符号的8位int转换为字符串时,我知道结果将始终最多为3个字符(对于255),而对于有符号的8位int我们需要4个字符。 “ -128”。

现在,我真正想知道的是浮点值是否相同。 将任何“ double”或“ float”值表示为字符串所需的最大字符数是多少?

假设使用常规的C / C ++双精度(IEEE 754)和普通的十进制扩展(即无%e printf格式)。

我什至不确定真正的小数(即0.234234)是否会比真正的大数(双精度数代表整数)长?

martin asked 2020-02-13T06:30:31Z
11个解决方案
34 votes

C中的标准标头-pow(2, DBL_MIN_EXP - DBL_MANT_DIG)或C ++中的标准标头DBL_MIN_EXP包含几个与浮点类型的范围和其他度量有关的常量。 其中之一是-pow(2,-N),它是表示所有3+N值所需的最大10乘幂。 由于"-0."需要N位数字来表示,并且也可能有负号,因此答案是

int max_digits = DBL_MAX_10_EXP + 2;

假设指数大于表示最大尾数所需的位数。 否则,还会有一个小数点,后跟更多位数。

更正

最长的数字实际上是最小的可表示的负数:它需要足够的数字来覆盖指数和尾数。 此值为-pow(2, DBL_MIN_EXP - DBL_MANT_DIG),其中DBL_MIN_EXP为负。 很容易看到(并通过归纳证明)-pow(2,-N)需要3+N个字符来表示非科学的十进制表示形式("-0.",后跟N个数字)。 所以答案是

int max_digits = 3 + DBL_MANT_DIG - DBL_MIN_EXP

对于64位IEEE double,我们有

DBL_MANT_DIG = 53
DBL_MIN_EXP = -1023
max_digits = 3 + 53 - (-1023) = 1079
Mike Seymour answered 2020-02-13T06:30:59Z
15 votes

根据IEEE 754-1985,用double类型表示的值的最长表示法,即:

-2.2250738585072020E-308

有24个字符。

Vitaliy Ulantikov answered 2020-02-13T06:31:27Z
4 votes

您可以使用snprintf()检查所需的字符数。snprintf()返回打印传递给它的内容所需的字符数。

/* NOT TESTED */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
    char dummy[1];
    double value = 42.000042; /* or anything else */
    int siz;
    char *representation;
    siz = snprintf(dummy, sizeof dummy, "%f", value);
    printf("exact length needed to represent 'value' "
           "(without the '\\0' terminator) is %d.\n", siz);
    representation = malloc(siz + 1);
    if (representation) {
        sprintf(representation, "%f", value);
        /* use `representation` */
        free(representation);
    } else {
        /* no memory */
    }
    return 0;
}

注意:snprintf()是C99函数。 如果C89编译器将其作为扩展提供,则它可能无法满足上述程序的预期。

编辑:将链接snprintf()更改为实际上描述C99标准施加的功能的链接; 原始链接中的描述有误。
2013:将链接更改回POSIX站点,我更喜欢第一次编辑的站点。

pmg answered 2020-02-13T06:32:01Z
4 votes

UC Berkely的第4页上的这些教科书注释,加上一些DIY计算,是比IEEE-754规范更详细的正确信息来源。 这些演讲幻灯片也对工程专业的学生很有帮助。

推荐的缓冲区大小

| Single| Double | Extended | Quad  |
|:-----:|:------:|:--------:|:-----:|
|   16  |  24    |    30    |  45   |

这些数字基于以下计算:

整数部分的最大小数

| Single| Double | Extended | Quad  |
|:-----:|:------:|:--------:|:-----:|
|   9   |   17   |    21    |  36   |

* Quantities listed in decimals.

小数计数基于以下公式:最多Ceiling(1 + NLog_10(2))个小数,其中N是整数部分中的位数*。

最大指数长度

| Single| Double | Extended | Quad  |
|:-----:|:------:|:--------:|:-----:|
|   5   |   5    |     7    |   7   |
* Standard format is `e-123`.

最快的算法

打印浮点数最快的算法是研究论文《快速,准确地打印浮点数》中详细介绍的Grisu2算法。 我可以找到的最佳基准可以在这里找到。

answered 2020-02-13T06:32:52Z
2 votes

通过设置精度将浮点数/双精度数转换为字符串时,可以控制字符串表示形式中的位数。 这样,最大位数将等于您指定的精度下的double的字符串表示形式。

#include <iostream>
#include <limits>
#include <sstream>
#include <iomanip>

int main()
{
 double x = std::numeric_limits<double>::max();

 std::stringstream ss;
 ss << std::setprecision(10) << std::fixed << x;

 std::string double_as_string = ss.str();
 std::cout << double_as_string.length() << std::endl;
}

因此,在double中,精度为10的最大位数是320位数。

Charles Salvia answered 2020-02-13T06:33:17Z
1 votes

取决于您所说的“代表”是什么意思。 小数部分没有精确的浮点表示形式。 当您转换十进制小数->二进制小数->十进制时,您没有精确的十进制表示形式,并且二进制表示形式的末尾会有噪声位。

这个问题不涉及从十进制开始,但是所有源代码(并且必须由用户输入)都是十进制,并且涉及可能的截断问题。 在这种情况下“精确”是什么意思?

基本上,这取决于您的浮点表示形式。

如果您有48位尾数,则大约需要16个十进制数字。 指数可能是剩余的14位(大约5个十进制数字)。

经验法则是位数约为小数位数的3倍。

S.Lott answered 2020-02-13T06:33:55Z
1 votes

1024是不够的,最小的负双精度值具有1077个十进制数字。 这是一些Java代码。

double x = Double.longBitsToDouble(0x8000000000000001L);
BigDecimal bd = new BigDecimal(x);
String s = bd.toPlainString();
System.out.println(s.length());
System.out.println(s);

这是程序的输出。

1077
-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625
Fred answered 2020-02-13T06:34:20Z
1 votes

“表示任何双精度值所需的最大字符长度是多少?”

这个问题的确切答案是:8个ASCII字符-以十六进制格式,不包括'0x'前缀-100%的精度:)(但这不只是一个玩笑)

IEEE-754 double的可用精度大约为16个十进制数字-因此,排除教育目的,表示时间长于此只是浪费资源和计算能力:

  • 当用户在屏幕上看到700位数时,用户并不会更加了解。

  • 以“更准确”的形式存储的配置变量是没有用的-在此编号上进行的每个操作都会破坏准确性。 (不包括更改符号位)

如果有人需要更好的真实精度,那么可以使用80位长的双精度数,精度约为18位。 libquadmath。

问候。

vtomazzi answered 2020-02-13T06:35:07Z
0 votes

假定二进制64 IEEE 754是您的274539044676252525699,则打印任何十进制2745390446762562525696值(即"%f"格式)所需的最大字符数将是-DBL_MIN(即-0x1p-1022)的值。 为此,您只需要325个字符。 那是:DBL_DIG + abs(DBL_MIN_10_EXP) + strlen("-0.")。这当然是因为log10(fabs(DBL_MIN))是308,也就是abs(DBL_MIN_10_EXP)+1(+1是因为小数点左边的前导数字),这是有效数字左边的前导零的数目。 。

int lz;                 /* aka abs(DBL_MIN_10_EXP)+1 */
int dplaces;
int sigdig;             /* aka DBL_DECIMAL_DIG - 1 */
double dbl = -DBL_MIN;

lz = abs((int) lrint(floor(log10(fabs(dbl)))));
sigdig = lrint(ceil(DBL_MANT_DIG * log10((double) FLT_RADIX)));
dplaces = sigdig + lz - 1;
printf("f = %.*f\n", dplaces, dbl);
Greg A. Woods answered 2020-02-13T06:35:28Z
0 votes

这根本不是模棱两可的响应。 我正在寻找可以告诉C#格式说明符的内容,以便执行我正在研究的解析器。 我随机生成一些测试用例,包括双精度或浮点精度常量,并且需要保留往返行程。 是的,我知道这是一个“往返”。 但是我还需要支持固定和科学计数法。 到目前为止,我喜欢1079,但这对我来说确实有点过分。 或者至少我的“足够接近”的比较需要将这种差异考虑到解析前/解析后的验证中。

mwpowellhtx answered 2020-02-13T06:35:49Z
-1 votes

“为此,您只需要325个字符”

显然(这是一种非常常见的情况),您不了解不同数字基数之间的转换是如何工作的。

不管DBL_MIN的定义多么精确,它都受到硬件精度的限制,硬件精度通常最多80位或18个十进制数字(x86和类似体系结构)

因此,像f.e.这样发明了专门的任意精度算术库。 gmp或mpfr。

vtomazzi answered 2020-02-13T06:36:22Z
translate from https://stackoverflow.com:/questions/1701055/what-is-the-maximum-length-in-chars-needed-to-represent-any-double-value