2017-09-02 3 views
0

Also versuche ich einen Code zu schreiben, der es mir erlaubt eine Zahl auf 3 Dezimalstellen aufzurunden. Mein Code für eine Reihe Aufrundung war wie folgt aus:Rundungsfunktion in C

for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) 
{ 
    for (columnIndex = 0; columnIndex < MAX_COLUMNS; columnIndex++) 
    { 
     printf("%.3f ", ceil(rawData[rowIndex][columnIndex] * 1000.0)/1000.0); 
    } 
} 

Aber gestern mein Lehrer sagte uns, um einen Code zu verwenden, die eine Struktur wie folgt hat:

float roundValue(float value, int decimalPlaces) 
{ 
     // Place rounding code here 
     return value; 
} 

ich bin nicht ganz sicher, wie man schreibt der Code in diesem Format! Ich bin ein Anfänger in der Programmierung, also könnte das so albern sein.

UPDATE: so habe ich nur alle Kommentare gelesen und versucht, den Code zu schreiben, aber immer noch ein Problem. Mein Code ist:

double roundValue(double value, int decimalPlaces) 
{ 
value = roundf(value * pow(10, decimalPlaces))/pow(10, decimalPlaces); 
return value; 
} 
int main(void) 
{ 
int rowIndex = 0; 
int columnIndex = 0; 
double rawData[MAX_ROWS][MAX_COLUMNS]; // 2-dimensional array to store our 
raw data 
double value = rawData[MAX_ROWS][MAX_COLUMNS]; 
int decimalPlaces = 3; 
// Print out the roundup data array 
printf(" --- ROUNDED DATA ---\n"); 
for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) 
{ 
    for (columnIndex = 0; columnIndex < MAX_COLUMNS; columnIndex++) 
    { 
     printf("%.3f ", roundValue(value, 3)); 
    } 
    printf("\n"); 
    } 
    return 0; 
} 

es gibt mir nur 0 für alle Zahlen.

+0

Sie müssen Ihre Fragen klären und Schritte beschreiben, die Sie bereits versucht haben ... – PureW

+1

Also, fragen Sie Ihren Lehrer? Und wenn Sie schon dabei sind, sagen Sie ihm, dass 'float' im Allgemeinen eine ** schreckliche ** Idee ist, wegen seiner begrenzten Präzision ... –

+0

Wenn Sie die Fließkomma-Binärdarstellung verstanden hätten, würden Sie nicht" * denken * "von 3 Nachkommastellen. Wenn Sie * WIRKLICH * 3 Dezimalstellen benötigen, versuchen Sie es mit einem Festkommaformat. –

Antwort

1

Basierend auf this answer, könnten Sie die roundf Funktion in math.h verwenden Sie:

#include <stdio.h> 
#include <math.h> 

/* function that rounds a float to the specified number of decimals */ 
float roundValue(float value, int decimalPlaces) 
{ 
    value = roundf(value * pow(10, decimalPlaces))/pow(10, decimalPlaces); 
    return value; 
} 


/*to see the results: */ 
int main() 
{ 
    float value = 12.34567; 
    printf("%f", roundValue(value, 3)); 
    return 0; 
} 

Compilation/run:

$ gcc -lm main.c 
$ ./a.out 
12.346000 
+0

Das ist natürlich keine Rundung um eine bestimmte Anzahl von Nachkommastellen, sondern nur durch einen linearen Faktor. – Ext3h

+1

@ Ext3h Könnten Sie bitte klären, was ist der Unterschied zwischen linearen Faktor und Nachkommastellen? – Steephen

+0

@Steephen Das "pow" fehlte in der ursprünglichen Version dieser Antwort. – Ext3h

1

Er sagte Sie nur Ihren Code in ein schreiben Funktion, die Sie in der main() Funktion aufrufen können.

Anstatt Ihren Code jedes Mal neu zu schreiben, wenn Sie einen runden Wert benötigen, können Sie eine Funktion verwenden, geben Sie die Zahl, für die Sie den runden Wert berechnen möchten, und Sie erhalten das Ergebnis, damit Ihr Code gewonnen hat. t sich wiederholend

0

Im Wesentlichen kann es nicht getan werden. Das Problem ist, dass 0,1 oder 0,001 nicht genau im Gleitkommaformat dargestellt werden können. Sie können also nur auf die nächste Darstellung runden = floor (x * 1000 + 0.5) /1000.0. Es ist am besten, die volle Genauigkeit des Double zu verwenden und dann im letzten Moment für die Anzeige zu runden.

printf("%.3g", x); 

wird dies für Sie erreichen. In Kombination mit strtod ist es auch eine andere Technik zum Runden.

+0

Die Verwendung von 'sprintf()' ist eine sinnvolle Alternative, aber mit '% .3g' 'Variantenausgabe mit großen Werten ist es sinnvoll, '"% .3f "' mit einem großen 'char []' zu verwenden. – chux

+0

Die Methode "floor (x * 1000 + 0.5)/1000.0" liefert falsche Ergebnisse für viele negative "x" und verschiedene positive "x", wobei "x + 0.5" nicht exakt ist. 'round (x * 1000.0)/1000.0;' wäre eine direkte Alternative. – chux

0

.. um eine Zahl auf 3 Dezimalstellen aufzurunden.
mein Lehrer sagte uns, um einen Code zu verwenden ... wie float roundValue(float value, int decimalPlaces)

Ohne sich auf eine höhere Präzision geht, ist es sehr schwierig, ist für alle value mit der besten Antwort OP Ziel gerecht zu werden.


einen schwimmenden Zeigerwert a) oder b) zum nächsten darstellbaren 0.001 (oder 10 -n) wird üblicherweise in Schritten Verrundung.

1) Multiplizieren mit 10 n
2) Rund a) oder b) zum nächsten
3) Divide by 10 n

float roundValue(float value, int decimalPlaces) { 
    // form the power of 10 
    assert(decimalPlaces >= 0 && decimalPlaces <= 9); 
    int power_of_10 = 1; 
    while (decimalPlaces-- > 0) power_of_10 *= 10; 
    double fpower_of_10 = power_of_10; // or just use `pow(10, decimalPlaces); 

Scaling von einer Leistung von 10 einführt Unschärfen . Dieser leichte Fehler wird im Rundungsschritt vergrößert. Ein einfaches Work-Around, um höhere Präzision Mathematik zu verwenden. Glücklicherweise begann das Codierungsziel mit einem float Wert und double hat oft eine höhere Genauigkeit.

Scaling durch eine Potenz von 10 Überlauf verursachen, aber das ist nicht wahrscheinlich wenn valuefloat ist und das Produkt ist double die ein breiteres Spektrum hat.

double y = value * fpower_of_10; 

    // round 
    double rounded_y = ceil(y); // round up 
    // or 
    double rounded_y = round(y); // round to nearest 

Der Quotient wird selten eine genaue Vielfaches von 0.001 (oder was auch immer Potenz-10) bieten, sondern ein Wert, der Gleitkomma- nahe ein Vielfaches von 0.001 ist.

y = rounded_y/fpower_of_10; 

    return y; 
} 

Nutzungs folgt. Daran erinnern, dass, wenn Ihre Fließkomma-Typen FLT_RADIX == 10 (sehr selten in diesen Tagen, in der Regel 2), das Ergebnis mit nur in der Nähe von die gewünschte "Zahl n Dezimalstellen.". Wenn es gut gemacht wird, ist das Ergebnis das nächstmögliche float/double.

printf("%f\n", roundValue(123.456789, 3)); 
printf("%.10f\n", roundValue(123.456789, 3)); // to see more 

Mehr: eine einfache Möglichkeit, Überlaufprobleme zu vermeiden, wenn eine höhere Genauigkeit nicht verfügbar ist oder verwendet wird, ist die große C-Werte variabel Punkte keine Bruchteil erkennen müssen, und keine Rundung benötigen.

float roundValue(float value, int decimalPlaces) { 
    float int_ptr; 
    float frac_part = modff(value, &int_ptr); 
    if (frac_part == 0) return value; 

    double pow10 = pow(10, decimalPlaces); 
    return round(value * pow10)/pow10; // or ceil() 
} 

Es gibt andere kleine subtile Probleme, die hier nicht erwähnt werden. double rounding, NaN, rounding mode, round() gegenüber rint(), nearbyint().