printf的宽度说明保持浮点值的precision [英] Printf width specifier to maintain precision of floating-point value

查看:144
本文介绍了printf的宽度说明保持浮点值的precision的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有可以适用于浮点说明,将输出自动设置到的显著数字的必要数量的printf 宽度说明>使得扫描串回来时,原来的浮点值被收购?

Is there a printf width specifier which can be applied to a floating point specifier that would automatically format the output to the necessary number of significant digits such that when scanning the string back in, the original floating point value is acquired?

例如,假设我打印浮动 2 的precision小数位:

For example, suppose I print a float to a precision of 2 decimal places:

float foobar = 0.9375;
printf("%.2f", foobar);    // prints out 0.94

当我扫描输出 0.94 ,我没有符合标准的保证,我会得到原始的 0.9375 浮点值回(在这个例子中,我可能不会)。

When I scan the output 0.94, I have no standards-compliant guarantee that I'll get the original 0.9375 floating-point value back (in this example, I probably won't).

我想办法告诉的printf 来自动浮点值打印到的显著数字的必要数量的,以确保其能扫描回传给原始值的printf

I would like a way tell printf to automatically print the floating-point value to the necessary number of significant digits to ensure that it can be scanned back to the original value passed to printf.

我可以使用一些宏在 float.h时推导最大宽度传递给的printf ,但有一个已经说明自动打印到的显著数字的必要号 - 或至少到最大宽度?

I could use some of the macros in float.h to derive the maximum width to pass to printf, but is there already a specifier to automatically print to the necessary number of significant digits -- or at least to the maximum width?

推荐答案

我建议@Jens Gustedt十六进制的解决方案:使用一个%

I recommend @Jens Gustedt hexadecimal solution: use %a.

OP要以最大的precision打印(或者至少是最显著十进制)。

OP wants "print with maximum precision (or at least to the most significant decimal)".

一个简单的例子是打印七分之一为:

A simple example would be to print one seventh as in:

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


但是,让我们深入挖掘...


But let's dig deeper ...

在数学上,答案是0.142857 142857 142857 ...,但我们使用有限precision浮点数。
假设 IEEE 754双precision二进制
因此, OneSeventh = 1.0 / 7.0 结果在下面的值。图中还显示了preceding和下面再presentable 双击浮点数。

Mathematically, the answer is "0.142857 142857 142857 ...", but we are using finite precision floating point numbers. Let's assume IEEE 754 double-precision binary. So the OneSeventh = 1.0/7.0 results in the value below. Also shown are the preceding and following representable double floating point numbers.

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

打印的确切的小数重presentation一个双击限制了用途。

Printing the exact decimal representation of a double has limited uses.

C有2个家庭的宏在&LT; float.h时方式&gt; 来帮助我们结果
第一组是的显著的数字来在一个字符串扫描字符串返回,所以当打印十进制数,
我们得到原始浮点。这里显示了C规格的的最小的值和的样品的C11编译器。

C has 2 families of macros in <float.h> to help us.
The first set is the number of significant digits to print in a string in decimal so when scanning the string back, we get the original floating point. There are shown with the C spec's minimum value and a sample C11 compiler.

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印刷,仍保持相同的字符串presentation。这里显示了C规格的的最小的值和的样品的C11编译器。我相信可得到pre-C99。

The second set is the number of significant digits a string may be scanned into a floating point and then the FP printed, still retaining the same string presentation. There are shown with the C spec's minimum value and a sample C11 compiler. I believe available pre-C99.

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

第一套宏似乎满足的显著的数字OP的目标。但是,这的的并不总是可用的。

The first set of macros seems to meet OP's goal of significant digits. But that macro is not always available.

#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是我的previous答案的关键所在。
它的中心,如果知道往返转换字符串-FP-字符串(#2宏可用C89),怎么会,来确定FP-字符串-FP(#1宏提供岗位C89)的数字?一般情况下,加3是结果。

The "+ 3" was the crux of my previous answer. Its centered on if knowing the round-trip conversion string-FP-string (set #2 macros available C89), how would one determine the digits for FP-string-FP (set #1 macros available post C89)? In general, add 3 was the result.

现在有多少的显著的数字打印是已知的,通过&LT驱动; FLOAT.H&GT;

Now how many significant digits to print is known and driven via <float.h>.

要打印传单N的显著的小数位数人们可以使用各种格式。

To print N significant decimal digits one may use various formats.

使用%E precision 的字段后的领先数字的数数字和小数点。
因此, - 1 正在有序进行。注:该 -1不是在初始 INT挖= DECIMAL_DIG;`

With "%e", the precision field is the number of digits after the lead digit and decimal point. So - 1 is in order. Note: This -1 is not in the initialint Digs = DECIMAL_DIG;`

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

使用%F precision 的字段后的小数位数的数点。
对于一些像 OneSeventh / 1000000.0 ,一会需要 OP_DBL_Digs + 6 来查看所有的显著数​​字。

With "%f", the precision field is the number of digits after the decimal point. For a number like OneSeventh/1000000.0, one would need OP_DBL_Digs + 6 to see all the significant digits.

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

请注意:许多人使用,以%F。显示小数点后6位;图6是显示缺省,数量不限的precision

Note: Many are use to "%f". That displays 6 digits after the decimal point; 6 is the display default, not the precision of the number.

这篇关于printf的宽度说明保持浮点值的precision的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆