1

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.

NeemzCr7
  • 63
  • 1
  • 9
  • You need to clarify your questions and describe steps you've already tried... – PureW Sep 02 '17 at 12:57
  • 1
    So, ask your teacher? And when you're at it, tell him using `float` is a **horrible** idea in general because of its limited precision ... –  Sep 02 '17 at 12:57
  • If you understood floating point binary representation you would not "*think*" of 3 decimal places. If you *REALLY* need 3 decimal places, try with a fixed point format. – Iharob Al Asimi Sep 02 '17 at 13:00
  • return ( value * 1000.0 ) / 1000.0 ); // copies your rounding code (maybe a better way tho) as the return in roundValue() – kenny Sep 02 '17 at 13:01
  • Read http://floating-point-gui.de/ – Basile Starynkevitch Sep 02 '17 at 15:25

4 Answers4

1

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
mikelsr
  • 457
  • 6
  • 13
1

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

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

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.

Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18
  • Using `sprintf()` is a reasonable alternative, yet with `"%.3g"` variant output with large values, it makes sense to use `"%.3f"` with a large `char []`. – chux - Reinstate Monica Sep 02 '17 at 19:39
  • The `floor(x * 1000 + 0.5)/1000.0` approach gives incorrect results for many negative `x` and various positive `x` where `x + 0.5` is not exact. `round(x * 1000.0)/1000.0;` would be a direct alternative. – chux - Reinstate Monica Sep 02 '17 at 19:42
0

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

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256