宏常量DECIMAL_DIG
是
可以转换为
long double
并返回而不会丢失精度的小数位数。
宏常量LDBL_DIG
是
可以在不失去
long double
精度的情况下表示的小数位数。
这两个定义有什么区别?是否存在使用一个而不是另一个可能导致错误结果的情况?
在我的计算机上DECIMAL_DIG == 21
,而LDBL_DIG == 18
。
来源:1
答案 0 :(得分:4)
之间有什么区别?
DECIMAL_DIG
和LDBL_DIG
(?)
首先:缩小问题范围
DECIMAL_DIG
(自C99起可用)适用于最宽浮点类型。对于C11,3种类型特定的宏FLT_DECIMAL_DIG
,DBL_DECIMAL_DIG
,LDBL_DECIMAL_DIG
意味着相同的东西,除了它们适用于相应的类型,而不是最宽的。< / p>
为了简化问题,让我们将LDBL_DECIMAL_DIG
与LDBL_DIG
进行比较,因为它们都处理相同的类型:long double
。
十进制文字表示 - &gt; long double
- &gt; 十进制文字表示。
LDBL_DIG
是此往返中始终产生相同起始值的文本的最大有效数字。
long double
- &gt; 十进制文字表示 - &gt; long double
。
LDBL_DECIMAL_DIG
是此往返所需文本的有效位数,始终会产生相同的起始long double
值。
如果浮点类型使用基数10表示,LDBL_DIG
和LDBL_DECIMAL_DIG
将具有相同的值。然而,大多数C实现使用二进制基数2而不是10:FLT_RADIX == 2
。
以下内容避免了深入的数学技术解释。
long double
不能代表十进制文本表示所具有的每个可能值。后者可以是s = "0.1234567890123456789012345678901234567890"
,而常见long double
也不能代表完全。将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_DIG
重要位数,则代码将始终成功long double
的所有值 - 成功往返。
s = "0.123456789012345678";
ld = strtold(s, (char **)NULL);
printf("%d\n%.*Le\n", LDBL_DIG, LDBL_DIG - 1, ld);
// 18
// 1.23456789012345678e-01
这篇文章Printf width specifier to maintain precision of floating-point value详细介绍了xxx_DECIMAL_DIG
系列宏的使用情况。它显示了将浮点值打印到文本然后转换回FP值并始终获得相同结果所需的有效位数。
注意:xxx_DECIMAL_DIG >= xxx_DIG
。
LDBL_DIG - 1
而不是LDBL_DIG
作为%.*Le
打印一个前导数字,然后输出指定的精确位数。总有效数字应为LDBL_DIG
。
答案 1 :(得分:1)
他们正在处理相反的往返方向。
DECIMAL_DIG
是从最大浮点类型转换为十进制字符串并返回时所需的小数位数,以确保您返回相同的值。 (当然,对于特定值,您可以使用较少的数字来获取,但如果您想要适用于任何值的数字,DECIMAL_DIG
就是它。)这是long double
- &gt ;十进制 - &gt; long double
往返。
LDBL_DIG
是从十进制转换为long double
并返回时可靠保留的小数位数。 (对于特定情况,当然可以保留更多。)这是小数 - &gt; long double
- &gt;十进制往返。
您引用的文字似乎具有误导性,可能完全错误,这是您对cppreference.com的期望。对于C或C ++的信息来说,这是一个非常糟糕的网站。
答案 2 :(得分:0)
<强> LBDL_DIG 强>:
可以舍入到浮点数并返回而不改变小数位数的小数位数。
和
小数位数q,这样任何带有q个十进制数字的浮点数都可以舍入为p基数为b的浮点数,然后再返回,而不会更改为q个十进制数字。
<强> DECIMAL_DIG 强>:
可以舍入为浮点类型并再次返回相同的十进制数字的小数位数,而不会损失精度。
和
小数位数n,使得具有pmax基数b位的最宽支持浮点类型中的任何浮点数可以舍入为具有n个十进制数字的浮点数,并且可以再次返回而不更改该值。
回答OP的问题: 它们以不同的方式计算。公式如上所述,是造成差异的原因。