C 十进制数字与LDBL数字之间的区别是什么<;浮动.h>;
宏常量C 十进制数字与LDBL数字之间的区别是什么<;浮动.h>;,c,floating-point,C,Floating Point,宏常量DECIMAL\u DIG是 可转换为长双精度且不损失精度的十进制位数 宏常量LDBL_DIG是 对于长双精度,可以在不损失精度的情况下表示的十进制位数 这两个定义有什么区别?是否存在一种情况,使用其中一种方法会导致不正确的结果 在我的机器上,DECIMAL\u DIG==21,而LDBL\u DIG==18 资料来源:LBDL\u DIG: 可以四舍五入为浮点并返回而不改变小数位数的小数位数 及 小数位数q,这样任何带有q个小数位数的浮点数都可以四舍五入为带有p个基数b位的浮点数,然后再
DECIMAL\u DIG
是
可转换为长双精度且不损失精度的十进制位数
宏常量LDBL_DIG是
对于长双精度
,可以在不损失精度的情况下表示的十进制位数
这两个定义有什么区别?是否存在一种情况,使用其中一种方法会导致不正确的结果
在我的机器上,DECIMAL\u DIG==21
,而LDBL\u DIG==18
资料来源:LBDL\u DIG: 可以四舍五入为浮点并返回而不改变小数位数的小数位数 及 小数位数q,这样任何带有q个小数位数的浮点数都可以四舍五入为带有p个基数b位的浮点数,然后再返回,而不会更改为q个小数位数 十进制\u DIG: 可以四舍五入到浮点类型并再次返回到相同的十进制数字的小数位数,而不会损失精度 及 小数位数,n,这样,任何支持最广泛的浮点类型的浮点数(pmax基数为b)都可以四舍五入为具有n个小数位数的浮点数,然后在不更改值的情况下再次返回 回答OP的问题: 它们是以不同的方式计算的。这些公式附在上面,是产生差异的原因
DECIMAL\u DIG
和LDBL\u DIG
之间有什么区别(?)
DECIMAL\u DIG
涉及最宽浮点类型到十进制文本到最宽浮点类型的转换。LDBL\u DIG
涉及十进制文本到long double
到十进制文本的转换
第一:缩小问题范围
DECIMAL\u DIG
(自C99起提供)适用于最宽的浮点类型。对于C11,3个特定于类型的宏FLT\u DECIMAL\u DIG
,DBL\u DECIMAL\u DIG
,LDBL\u DECIMAL\u DIG
的含义相同,只是它们适用于相应的类型,而不是最宽的类型
为了简化问题,让我们将LDBL\u DECIMAL\u DIG
与LDBL\u DIG
进行比较,因为它们都处理相同的类型:long double
十进制文本表示法-->
长双精度
-->十进制文本表示法。LDBL\u DIG
是文本的最大有效位,在该往返过程中始终会产生相同的起始值
long-double
-->十进制文本表示法-->long-double
LDBL\u DECIMAL\u DIG
是此往返过程中需要的文本有效位数,以始终产生相同的起始long double
值
如果浮点类型使用以10为基数的表示形式,LDBL\u DIG
和LDBL\u DECIMAL\u DIG
将具有相同的值。然而,大多数C实现使用二进制基数2而不是10:FLT_基数==2
以下内容避免了深入的数学技术解释
long double
不能像十进制文本表示法那样表示所有可能的值。后者可以是s=“0.12345678901213456789012345678901234567890”
而普通长双精度
不能准确表示这一点。将s
转换为long double
并返回到文本不会返回相同的结果
char *s = "0.1234567890123456789012345678901234567890";
long double ld = strtold(s, (char **)NULL);
printf("%.40Le\n", ld);
// typical output v -- different
// 1.2345678901234567890132180073559098332225e-01
但是,如果我们将文本输入限制为LDBL\u DIG
有效数字,则对于长双精度
-往返的所有值,代码将始终成功
s = "0.123456789012345678";
ld = strtold(s, (char **)NULL);
printf("%d\n%.*Le\n", LDBL_DIG, LDBL_DIG - 1, ld);
// 18
// 1.23456789012345678e-01
这篇文章详细介绍了xxx\u DECIMAL\u DIG
宏系列的使用。它显示将浮点值打印为文本,然后转换回FP值并始终获得相同结果所需的有效位数
char *s = "0.1234567890123456789012345678901234567890";
long double ld = strtold(s, (char **)NULL);
printf("%.40Le\n", ld);
// typical output v -- different
// 1.2345678901234567890132180073559098332225e-01
注:
xxx\u DECIMAL\u DIG>=xxx\u DIG
上面使用的LDBL_DIG-1
而不是LDBL_DIG
作为%.*Le
打印一个前导数字,然后打印指定精度的位数。总有效位计数应为LDBL\u DIG
----
需要回答的进一步信息
第一个定义很接近,但不完整。LDBL\u DIG
指文本-->long double
-->文本需要
LDBL\u DIG
OP's:“可以在不损失长双精度的情况下表示的小数位数。”
C规范:“十进制数字的数量,q,这样任何带有q十进制数字的浮点数都可以四舍五入为带有p基数b数字的浮点数,然后再返回,而不更改为q十进制数字,”
q=地板((p-1)*log10b)
对于OP的机器,有p==64和b==2-->q==18
因此,对于正常的long double
范围,具有多达18位有效数字的十进制数字(如文本)可以转换为long double
,然后再转换回文本中的18位数字,并始终获得起始文本值
DECIMAL\u DIG
第二种定义是错误的。DECIMAL\u DIG
指的是long double
-->文本-->long double
需要。OP的定义是文本对
长双精度对文本
OP's:“可转换为长双精度和反精度的小数位数。”
C规范:“十进制数字的数量,n,这样,任何支持最广泛的浮点类型的浮点数(pmax基数为b)都可以四舍五入为一个具有n个十进制数字的浮点数,然后再返回,而不改变其值,”
n=ceil(1+pmax