SORU
10 Kasım 2008, PAZARTESİ


Printf sıfır sondaki()önlemek

Printf için Biçim belirteçleri üzerine tökezleyerek devam ediyorum() işlevleri aile. İstediğim virgülden sonra basamak belirli bir sayı ile bir çift (veya yüzer) baskı almak için. Eğer kullanırsam:

printf("%1.3f", 359.01335);
printf("%1.3f", 359.00999);

Anladım

359.013
359.010

Yerine istediğiniz

359.013
359.01

Biri bana yardımcı olabilir mi?

CEVAP
10 Kasım 2008, PAZARTESİ


Bu printf normal format belirteçleri ile yapılabilir. Alabileceğin en yakın olacaktır:

printf("%.6g", 359.013); // 359.013
printf("%.6g", 359.01);  // 359.01

".6". ama ^em>toplamsayısal genişlik

printf("%.6g", 3.01357); // 3.01357

onu kıramaz.

Sana neolabilirsprintf("%.20g") dize sayısı dize yalnızca ondalık noktadan N karakter için manipüle tampon etmektir.

Numaranızı değişken sayı olduğunu varsayarsak, aşağıdaki işlevi tüm N ilk ondalık kaldırmak, ardarda sıfırları (ve eğer sıfır olsaydı ondalık noktası) kapalı şerit.

char str[50];
sprintf (str,"%.20g",num);  // Make the number.
morphNumericString (str, 3);
:    :
void morphNumericString (char *s, int n) {
    char *p;
    int count;

    p = strchr (s,'.');         // Find decimal point, if any.
    if (p != NULL) {
        count = n;              // Adjust for more or less decimals.
        while (count >= 0) {    // Maximum decimals allowed.
             count--;
             if (*p == '\0')    // If there's less than desired.
                 break;
             p  ;               // Next character.
        }

        *p-- = '\0';            // Truncate string.
        while (*p == '0')       // Remove trailing zeros.
            *p-- = '\0';

        if (*p == '.') {        // If all decimals were zeros, remove ".".
            *p = '\0';
        }
    }
}

Eğer memnun değilseniz kesme yönü (hangi devre 0.12399 0.123 yerine yuvarlama 0.124), aslında yuvarlama imkanı sağlanması printf. Sadece elden önce dinamik olarak genişliklerini oluşturmak, bu bir dize içine numarasını çevirmek için kullanın sayısını analiz etmek gerekir:

#include <stdio.h>

void nDecimals (char *s, double d, int n) {
    int sz; double d2;

    // Allow for negative.

    d2 = (d >= 0) ? d : -d;
    sz = (d >= 0) ? 0 : 1;

    // Add one for each whole digit (0.xx special case).

    if (d2 < 1) sz  ;
    while (d2 >= 1) { d2 /= 10.0; sz  ; }

    // Adjust for decimal point and fractionals.

    sz  = 1   n;

    // Create format string then use it.

    sprintf (s, "%*.*f", sz, n, d);
}

int main (void) {
    char str[50];
    double num[] = { 40, 359.01335, -359.00999,
        359.01, 3.01357, 0.111111111, 1.1223344 };
    for (int i = 0; i < sizeof(num)/sizeof(*num); i  ) {
        nDecimals (str, num[i], 3);
        printf ("0.20f -> %s\n", num[i], str);
    }
    return 0;
}

Bu durumda nDecimals() bütün mesele doğru alan genişlikleri çalışmak, sonra Biçim dizi o dayalı bir biçim dizesi kullanarak. Test koşum main() bu eylemi gösterir:

  40.00000000000000000000 -> 40.000
 359.01335000000000263753 -> 359.013
-359.00999000000001615263 -> -359.010
 359.00999999999999090505 -> 359.010
   3.01357000000000008200 -> 3.014
   0.11111111099999999852 -> 0.111
   1.12233439999999995429 -> 1.122

Doğru yuvarlanmış değeri bir kez, bir kez daha morphNumericString() bunu sadece değiştirerek sondaki sıfırları kaldırmak geçirebilirsiniz:

nDecimals (str, num[i], 3);

içine:

nDecimals (str, num[i], 3);
morphNumericString (str, 3);

(veya nDecimals sonunda morphNumericString ama, bu durumda, muhtemelen sadece bir fonksiyonu içine iki birleştirmek istiyorum arama) ve sonunda:

  40.00000000000000000000 -> 40
 359.01335000000000263753 -> 359.013
-359.00999000000001615263 -> -359.01
 359.00999999999999090505 -> 359.01
   3.01357000000000008200 -> 3.014
   0.11111111099999999852 -> 0.111
   1.12233439999999995429 -> 1.122

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • CNET

    CNET

    5 Mayıs 2006
  • dirkgently1

    dirkgently1

    13 NİSAN 2006
  • Matt Davis

    Matt Davis

    4 ŞUBAT 2006