Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 表示任何双精度值所需的最大长度(以字符为单位)是多少?_C++_C_Floating Point - Fatal编程技术网

C++ 表示任何双精度值所需的最大长度(以字符为单位)是多少?

C++ 表示任何双精度值所需的最大长度(以字符为单位)是多少?,c++,c,floating-point,C++,C,Floating Point,当我将无符号8位整数转换为字符串时,我知道结果将始终最多为3个字符(对于255),对于有符号8位整数,我们需要4个字符,例如“-128” 现在我想知道的是浮点值也是一样的。将任何“double”或“float”值表示为字符串所需的最大字符数是多少 假设使用常规的C/C++双精度(IEEE 754)和正常的十进制扩展(即没有%e printf格式) 我甚至不确定真正的小数字(即0.234234)是否会比真正的大数字(表示整数的双精度数)长。取决于你所说的“表示”是什么意思。小数没有精确的浮点表示。

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

现在我想知道的是浮点值也是一样的。将任何“double”或“float”值表示为字符串所需的最大字符数是多少

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


我甚至不确定真正的小数字(即0.234234)是否会比真正的大数字(表示整数的双精度数)长。

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

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

基本上,它取决于您的浮点表示

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

经验法则是位的数量大约是十进制数字数量的3倍。

根据,用双精度类型表示值的最长符号,即:

-2.2250738585072020E-308


具有24个字符

当您通过设置精度将浮点/双精度转换为字符串时,可以控制字符串表示形式中的位数。然后,最大位数将等于指定精度的
std::numeric\u limits::max()
的字符串表示形式

#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;
}
#包括
#包括
#包括
#包括
int main()
{
双x=std::数值限制::max();
std::stringstream-ss;

SS<标准> C中的标准标题“代码> <代码> >或C++中的代码> <代码>,包含与浮点类型的范围和其他度量相关的几个常数。其中之一是“代码> dBLYMAX 1010XEP < /C>,代表所有代码< 2>代码>值所需的最大幂-10指数。代表,也可能有一个否定的符号,那么答案是

int max_digits = DBL_MAX_10_EXP + 2;
int max_digits = 3 + DBL_MANT_DIG - DBL_MIN_EXP
这假设指数大于表示最大可能尾数值所需的位数;否则,小数点后还会有更多位数

校正

最长的数字实际上是最小的可表示负数:它需要足够的数字来覆盖指数和尾数。这个值是
-pow(2,DBL\u MIN\u EXP-DBL\u MANT\u DIG)
,其中
DBL\u MIN\u EXP
是负数。很容易看出(并通过归纳证明)
-pow(2,-N)
需要
3+N
字符作为非科学十进制表示(
“-0.”
,后跟
N
数字)。因此答案是

int max_digits = DBL_MAX_10_EXP + 2;
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
您可以使用来检查需要多少字符。
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;
}
/*未测试*/
#包括
#包括
内部主(空){
伪字符[1];
双精度值=42.000042;/*或任何其他值*/
int siz;
字符*表示;
siz=snprintf(dummy,sizeof dummy,“%f”,值);
printf(“表示‘值’所需的精确长度”
“(不带“\\0”终止符)为%d.\n”,大小为;
代表性=malloc(siz+1);
国际单项体育联合会(代表){
sprintf(表示法,“%f”,值);
/*使用“表示法”*/
自由(代表);
}否则{
/*没有记忆*/
}
返回0;
}
注意
snprintf()
是一个C99函数。如果C89编译器将其作为扩展提供,则可能无法实现上述程序的预期功能

编辑: 将指向
snprintf()
的链接更改为实际描述C99标准规定的功能的链接;中的描述错误。

2013:将链接改回POSIX站点,我更喜欢它。

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
“表示任何双精度值所需的最大长度(以字符为单位)是多少?”

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

IEEE-754 double的可用精度约为16位小数-因此,排除教育目的,表示长度超过16位仅是浪费资源和计算能力:

  • 当用户在屏幕上看到700位数字时,他们并没有得到更多的信息

  • 以“更精确”形式存储的配置变量是无用的-对该数字的每一次操作都会破坏精度。(不包括更改符号位)

如果有人需要更好的实际精度,那么有80位长的双精度,精度约为18位,或者f.e.libquadmath


关于。

打印任何十进制
双精度
值(即
%f”
格式)所需的最大字符数为
-DBL_MIN
(即-0x1p-1022,假设二进制64 IEEE 754是您的
双精度
)这当然是因为
log10(fabs(DBL__MIN)是308,也就是
abs(DBL_MIN_10_EXP)+strlen(“-0”)
| Single| Double | Extended | Quad  |
|:-----:|:------:|:--------:|:-----:|
|   9   |   17   |    21    |  36   |

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