Saya merekomendasikan solusi heksadesimal @Jens Gustedt: gunakan% a.
OP menginginkan "mencetak dengan presisi maksimum (atau setidaknya hingga desimal paling signifikan)".
Contoh sederhananya adalah mencetak satu ketujuh seperti di:
#include <float.h>
int Digs = DECIMAL_DIG;
double OneSeventh = 1.0/7.0;
printf("%.*e\n", Digs, OneSeventh);
// 1.428571428571428492127e-01
Tapi mari kita gali lebih dalam ...
Secara matematis, jawabannya adalah "0.142857 142857 142857 ...", tetapi kami menggunakan angka floating point presisi hingga. Mari kita asumsikan biner presisi ganda IEEE 754 . Jadi OneSeventh = 1.0/7.0
hasilnya di nilai dibawah ini. Juga ditampilkan double
bilangan floating point sebelum dan sesudahnya.
OneSeventh before = 0.1428571428571428 214571170656199683435261249542236328125
OneSeventh = 0.1428571428571428 49212692681248881854116916656494140625
OneSeventh after = 0.1428571428571428 769682682968777953647077083587646484375
Mencetak representasi desimal yang tepat dari a double
memiliki kegunaan terbatas.
C memiliki 2 keluarga makro <float.h>
untuk membantu kami.
Set pertama adalah jumlah digit signifikan untuk dicetak dalam string dalam desimal sehingga saat memindai string kembali, kami mendapatkan titik mengambang asli. Ada yang ditampilkan dengan nilai minimum spesifikasi C dan kompiler C11 sampel .
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)
Set kedua adalah jumlah digit signifikan sebuah string dapat dipindai menjadi floating point dan kemudian FP dicetak, masih mempertahankan presentasi string yang sama. Ada yang ditampilkan dengan nilai minimum spesifikasi C dan kompiler C11 sampel . Saya yakin tersedia pra-C99.
FLT_DIG 6, 6 (float)
DBL_DIG 10, 15 (double)
LDBL_DIG 10, 18 (long double)
Set makro pertama tampaknya memenuhi tujuan OP untuk digit signifikan . Tetapi makro itu tidak selalu tersedia.
#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" adalah inti dari jawaban saya sebelumnya. Ini berpusat pada jika mengetahui konversi bolak-balik string-FP-string (set # 2 makro tersedia C89), bagaimana cara menentukan digit FP-string-FP (set # 1 makro tersedia pos C89)? Secara umum, tambahkan 3 adalah hasilnya.
Sekarang berapa banyak angka penting yang akan dicetak diketahui dan didorong <float.h>
.
Untuk mencetak N digit desimal signifikan, seseorang dapat menggunakan berbagai format.
Dengan "%e"
, bidang presisi adalah jumlah digit setelah digit awal dan titik desimal. Begitu - 1
juga dengan ketertiban. Catatan: Ini -1
bukan di awalint Digs = DECIMAL_DIG;
printf("%.*e\n", OP_DBL_Digs - 1, OneSeventh);
// 1.4285714285714285e-01
Dengan "%f"
, bidang presisi adalah jumlah digit setelah koma desimal. Untuk angka seperti OneSeventh/1000000.0
, seseorang perlu OP_DBL_Digs + 6
melihat semua angka penting .
printf("%.*f\n", OP_DBL_Digs , OneSeventh);
// 0.14285714285714285
printf("%.*f\n", OP_DBL_Digs + 6, OneSeventh/1000000.0);
// 0.00000014285714285714285
Catatan: Banyak yang terbiasa "%f"
. Itu menampilkan 6 digit setelah koma desimal; 6 adalah tampilan default, bukan ketepatan angka.