为了账号安全,请及时绑定邮箱和手机立即绑定

保持浮点值精度的Printf宽度说明符

保持浮点值精度的Printf宽度说明符

开心每一天1111 2019-06-11 13:10:23
保持浮点值精度的Printf宽度说明符有没有printf宽度说明符,可应用于浮点说明符,该说明符将自动将输出格式化为所需的有效数字这样,当扫描返回字符串时,获取原始浮点值?例如,假设我打印一个float精确到2小数位:float foobar = 0.9375;printf("%.2f", foobar);    // prints out 0.94当我扫描输出时0.94,我没有符合标准的保证,我会得到原来的0.9375浮点值返回(在本例中,我可能不会)。我想找个方法告诉你printf将浮点值自动打印到所需的有效数字以确保可以将其扫描回传递给printf.我可以使用一些宏float.h到求出最大宽度传给printf,但是是否已经有一个说明符可以自动打印到所需的有效数字-或者至少达到最大宽度?
查看完整描述

3 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

十六进制解决方案:使用%a。

OP想要“具有最大精度的打印(或至少到最重要的十进制)”。

一个简单的例子是打印七分之一,如下所示:

#include <float.h>int Digs = DECIMAL_DIG;double OneSeventh = 1.0/7.0;printf("%.*e\n", Digs, OneSeventh);// 1.428571428571428492127e-01

但让我们深入挖掘.。

数学上,答案是“0.142857 142857 142857.”,但我们使用的是有限精度浮点数。让我们假设IEEE 754双精度二进制..所以OneSeventh = 1.0/7.0结果如下所示。还显示了前面和下面的可表示double浮点数。

OneSeventh before = 0.1428571428571428 214571170656199683435261249542236328125OneSeventh        
= 0.1428571428571428 49212692681248881854116916656494140625OneSeventh after  = 0.1428571428571428 769682682968777953647077083587646484375

打印精确性的十进制表示double用途有限。

C中有两个宏家族。<float.h>帮助我们。
第一组是显着用十进制字串打印的数字,所以当扫描返回字符串时,我们得到原始浮点数。这里显示的是C规范最小值价值和a样本c11编译器

FLT_DECIMAL_DIG   6,  9 (float)                           (C11)DBL_DECIMAL_DIG  10, 17 (double)                    
      (C11)LDBL_DECIMAL_DIG 10, 21 (long double)                     (C11)DECIMAL_DIG      
      10, 21 (widest supported floating type)  (C99)

第二组是显着数字字符串可以扫描成浮点,然后打印FP,仍然保留相同的字符串表示形式。这里显示的是C规范最小值价值和a样本c11编译器我相信在C99之前就有了。

FLT_DIG   6, 6 (float)DBL_DIG  10, 15 (double)LDBL_DIG 10, 18 (long double)

第一组宏似乎符合OP的目标显着数字。但那并不总是可用的。

#ifdef DBL_DECIMAL_DIG  #define OP_DBL_Digs (DBL_DECIMAL_DIG)#else  
  #ifdef DECIMAL_DIG    #define OP_DBL_Digs (DECIMAL_DIG)
  #else  
    #define OP_DBL_Digs (DBL_DIG + 3)
  #endif#endif

“+3”是我先前回答的关键。如果知道往返转换字符串-fp-string(SET#2宏可用C89),那么如何确定fp-string-fp(SET#1宏可用后C89)的数字?总的来说,Add 3就是结果。

现在有多少显着要打印的数字是已知的,并通过<float.h>.

打印N显着十进制数字可以使用各种格式。

带着"%e"精密度字段是数字的数目。领头数字和小数点。所以- 1是合乎情理的。注:此-1 is not in the initialINDIG=十进制_DIG;

printf("%.*e\n", OP_DBL_Digs - 1, OneSeventh);// 1.4285714285714285e-01

带着"%f"精密度字段是数字的数目。小数点。像这样的数字OneSeventh/1000000.0,一个人需要OP_DBL_Digs + 6去看所有的显着数字。

printf("%.*f\n", OP_DBL_Digs    , OneSeventh);// 0.14285714285714285printf("%.*f\n", OP_DBL_Digs + 6, OneSeventh/1000000.0);
// 0.00000014285714285714285

注:许多人习惯于"%f"..它在小数点之后显示6位数字;6是显示默认值,而不是数字的精度。


查看完整回答
反对 回复 2019-06-11
?
PIPIONE

TA贡献1829条经验 获得超9个赞

不丢失地打印浮点数的简短答案(因此可以将它们读回完全相同的数字,但NaN和Infinity除外):

  • 如果您的类型是浮动的:使用

    printf("%.9g", number).

  • 如果您的类型是双重的:使用

    printf("%.17g", number).

不使用%f,因为这仅指定小数之后的有效位数,并将截断小数字。作为参考,魔幻数字9和17可以在float.h它定义了FLT_DECIMAL_DIGDBL_DECIMAL_DIG.


查看完整回答
反对 回复 2019-06-11
?
ITMISS

TA贡献1871条经验 获得超8个赞

如果您只对位(resp十六进制模式)感兴趣,则可以使用%a格式。这保证你:

如果存在基2中的精确表示,并且在其他情况下足够大,足以区分类型Double的值,则默认精度就足以表示值的精确表示。

我必须补充一点,这是只有在C99之后才能使用的。


查看完整回答
反对 回复 2019-06-11
  • 3 回答
  • 0 关注
  • 774 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信