@Jens Gustedt onaltılık çözümü öneriyorum:% a kullanın.
OP, "maksimum hassasiyetle (veya en azından en önemli ondalık basamağa kadar) yazdırmak" istiyor.
Basit bir örnek, yedide birini aşağıdaki gibi yazdırmak olabilir:
#include <float.h>
int Digs = DECIMAL_DIG;
double OneSeventh = 1.0/7.0;
printf("%.*e\n", Digs, OneSeventh);
// 1.428571428571428492127e-01
Ama daha derine inelim ...
Matematiksel olarak cevap "0.142857 142857 142857 ...", ancak sonlu hassas kayan noktalı sayılar kullanıyoruz. IEEE 754 çift duyarlıklı ikili varsayalım . Yani OneSeventh = 1.0/7.0
sonuçlar aşağıdaki değerde. Ayrıca, önceki ve sonraki gösterilebilir double
kayan nokta sayıları da gösterilmiştir .
OneSeventh before = 0.1428571428571428 214571170656199683435261249542236328125
OneSeventh = 0.1428571428571428 49212692681248881854116916656494140625
OneSeventh after = 0.1428571428571428 769682682968777953647077083587646484375
A'nın tam ondalık gösterimini yazdırmanın double
sınırlı kullanımı vardır.
C'nin <float.h>
bize yardımcı olacak 2 makro ailesi vardır .
İlk küme, bir dizede ondalık olarak yazdırılacak anlamlı basamakların sayısıdır, bu nedenle dizeyi geri tararken, orijinal kayan noktayı elde ederiz. C spesifikasyonunun minimum değeri ve örnek bir C11 derleyicisi ile gösterilmiştir.
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)
İkinci küme, bir dizinin bir kayan noktaya taranabileceği ve ardından FP'nin yazdırıldığı, hala aynı dizi sunumunu koruyan önemli basamakların sayısıdır . C spesifikasyonunun minimum değeri ve örnek bir C11 derleyicisi ile gösterilmiştir. C99 öncesi mevcut olduğuna inanıyorum.
FLT_DIG 6, 6 (float)
DBL_DIG 10, 15 (double)
LDBL_DIG 10, 18 (long double)
İlk makro kümesi, OP'nin önemli basamak hedefini karşılamaktadır . Ancak bu makro her zaman mevcut değildir.
#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" önceki cevabımın en önemli noktasıydı. Eğer gidiş-dönüş dönüşüm dizisi-FP-dizesini (set # 2 makroları mevcut C89) biliyorsanız, FP-string-FP için basamakları nasıl belirlenir (C89 sonrası mevcut küme # 1 makroları)? Genel olarak, sonuç 3'tür.
Şimdi yazdırılacak kaç önemli basamak biliniyor ve yönlendiriliyor <float.h>
.
N önemli ondalık basamağı yazdırmak için çeşitli formatlar kullanılabilir.
İle "%e"
, kesinlik alanı, ön basamak ve ondalık noktadan sonraki basamak sayısıdır . Yani - 1
sırada bulunuyor. Not: Bu -1
başlangıçta değilint Digs = DECIMAL_DIG;
printf("%.*e\n", OP_DBL_Digs - 1, OneSeventh);
// 1.4285714285714285e-01
İle "%f"
, kesinlik alanı ondalık noktadan sonraki basamak sayısıdır . Gibi bir sayı için OneSeventh/1000000.0
, OP_DBL_Digs + 6
tüm önemli basamakları görmeniz gerekir .
printf("%.*f\n", OP_DBL_Digs , OneSeventh);
// 0.14285714285714285
printf("%.*f\n", OP_DBL_Digs + 6, OneSeventh/1000000.0);
// 0.00000014285714285714285
Not: Birçoğu için kullanılır "%f"
. Bu, ondalık noktadan sonra 6 basamak görüntüler; Sayının kesinliği değil, varsayılan değer 6'dır.