NeemzCr7
NeemzCr7

Reputation: 63

Rounding function in C

So i am trying to write a code which can allow me to round UP any number to 3 decimal places. My code for rounding up a number was like this :

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

But yesterday my teacher told us to use a code which has a structure like this:

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

i am not quite sure how to write the code in this format! I am a beginner in coding so this might be so silly.

UPDATE: so i just read all the comments below and tried to write the code but still has a problem. my code is :

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;
}

it gives me only 0 for all the numbers.

Upvotes: 1

Views: 2711

Answers (4)

chux
chux

Reputation: 154592

.. to round UP any number to 3 decimal places.
my teacher told us to use a code ... like float roundValue(float value, int decimalPlaces)

Without going to higher precision, it is very difficult to meet OP's goal with the best answer for all value.


Rounding a floating pointer value a) up or b) to the nearest representable 0.001 (or 10-n) is usually done in steps.

1) Multiply by 10n
2) Round a) up or b) to nearest
3) Divide by 10n

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 by a power of 10 introduces imprecision. This slight error is magnified in the rounding step. A simple work-around it to use higher precision math. Fortunately the coding goal started with a float value and double often has higher precision.

Scaling by a power-of 10 can cause overflow, yet that is not likely when value is float and the product is double which has a wider range.

  double y = value * fpower_of_10;

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

The quotient will rarely provide an exact multiple of 0.001 (or whatever power-of-10) but a floating point value that is near a multiple of 0.001.

  y = rounded_y / fpower_of_10;

  return y;
}

Usage follows. Recall that unless your floating point types use a FLT_RADIX == 10 (very rare these days, usually 2), The result with only be near the desired "number to n decimal places.". If done well, the result will be the nearest possible float/double.

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

More: an easy way to avoid overflow issues if higher precision is not available or used is to recognize that great C floating-points values have no fractional part and need no rounding.

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()
}

There are other small subtle issues not noted here. double rounding, NaN, rounding mode, round() vs. rint(), nearbyint().

Upvotes: 0

Saad ELALLAM
Saad ELALLAM

Reputation: 21

He just told you to write your code in a function that you can call in the main() function.

So instead of rewriting your code every time you need a round value you can use a function, you give it the number that you want to calculate the round value for, and it will give you the result so your code won't be repetitive

Upvotes: 1

Malcolm McLean
Malcolm McLean

Reputation: 6404

Essentially it can't be done. The problem is that 0.1, or 0.001, cannot be represented in floating point format exactly. So you can only round to the nearest representation rounded = floor(x * 1000 + 0.5)/1000.0. It's best to use the full accuracy of the double, then round at the last moment, for display.

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

will achieve this for you. In combination with strtod it's also another technique for rounding.

Upvotes: 0

mikelsr
mikelsr

Reputation: 457

Based on this answer, you could use the roundf function found in math.h:

#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

Upvotes: 1

Related Questions