3

So I am a second semester freshman in college. My teacher wants us to write a function that round a floating point number to the nearest hundredth. He said that we need to convert the floating point into an integer data type and then covert it back to a floating point. That's all he said. I have spent at least 5 hours trying different ways to do this.

This is my code so far:

#include <stdio.h>

int rounding(int roundedNum);
int main()
{
   float userNum,
         rounded;

   printf("\nThis program will round a number to the nearest hundredths\n");
   printf("\nPlease enter the number you want rounded\n>");

   scanf("%f", &userNum);

   rounded = rounding (userNum);

   printf("%f rounded is %f\n", userNum, rounded);

   return 0;
}

int rounding(int roundedNum)
{


   return roundedNum;
}
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
JacobSedlik19
  • 31
  • 1
  • 2
  • 2
    Well it's very hard to answer this without giving you the straight answer, I guess the best hint I can give you is this: If you take `1.51` and want to round to `1.5` (tenths), you could start by multiplying by `10`. Which yields 15.1, cast that to an `int` for `15` and then divide by `10.0` for `1.5`. Hope that helps. – Elliott Frisch Feb 27 '18 at 04:18
  • Try multiplying by a number X, casting to an int and then dividing by the floating point version of X. – Asleepace Feb 27 '18 at 04:18
  • 1
    "and then co[n]vert it back to a floating point": that doesn't seem to make sense, since not every floating point number, certainly not with .01 significance, can be represented exactly by a float in binary. –  Feb 27 '18 at 04:19
  • Start by changing `int rounding(int roundedNum)` to accept and return a `float`. – chux - Reinstate Monica Feb 27 '18 at 04:25
  • So change it to "int rounding(float roundedNum)"? – JacobSedlik19 Feb 27 '18 at 04:28
  • 1
    Your teacher needs to read [this](https://stackoverflow.com/a/12684082/207421). He is talking Grade A drivel. – user207421 Feb 27 '18 at 04:30
  • Casting to `int` doesn't round, it truncates. The usual definition of rounding does not involve truncation. You can circumvent this issue a bit by adding (or subtracting, for negative numbers) `0.5` (after multiplication by 100), though even then you have [numerous variants of rounding values](https://en.wikipedia.org/wiki/Rounding#Rounding_to_integer). –  Feb 27 '18 at 05:01

5 Answers5

2

Your instructor may be thinking:

float RoundHundredth(float x)
{
    // Scale the hundredths place to the integer place.
    float y = x * 100;

    // Add .5 to cause rounding when converting to an integer.
    y += .5f;

    // Convert to an integer, which truncates.
    int n = y;

    // Convert back to float, undo scaling, and return.

    return n / 100.f;
}

This is a flawed solution because:

  • Most C implementations use binary floating point. In binary floating-point, it is impossible to store any fractions that are not multiples of a negative power of two (½, ¼, ⅛, 1/16, 1/32, 1/64,…). So 1/100 cannot be exactly represented. Therefore, no matter what calculations you do, it is impossible to return exactly .01 or .79. The best you can do is get close.

  • When you perform arithmetic on floating-point numbers, the results are rounded to the nearest representable value. This means that, in x * 100, the result is, in generally, not exactly 100 times x. There is a small error due to rounding. This error cause push the value across the point where rounding changes from one direction to another, so it can make the answer wrong. There are techniques for avoiding this sort of error, but they are too complicated for introductory classes.

  • There is no need to convert to an integer to get truncation; C has a truncation function for floating-point built-in: trunc for double and truncf for float.

  • Additionally, the use of truncation in converting to integer compelled us to add ½ to get rounding instead. But, once we are no longer using a conversion to an integer type to get an integer value, we can use the built-in function for rounding floating-point values to integer values: round for double and roundf for float.

If your C implementation has good formatted input/output routines, then an easy way to find the value of a floating-point number rounded to the nearest hundred is to format it (as with snprintf) using the conversion specifier %.2f. A proper C implementation will convert the number to decimal, with two digits after the decimal point, using correct rounding that avoids the arithmetic rounding errors mentioned above. However, then you will have the number in string form.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • This is almost exactly as he wanted. I submitted the program and only got marked off for forgetting my comment above the function anda space in between the function declaration and main. Thank you for your comment. It did help me understand what i needed to do. – JacobSedlik19 Mar 03 '18 at 05:26
0

Here are some hints:

  1. Multiply float with "some power of 10" to ensure the needed precision numbers are shifted left

  2. Cast the new value to a new int variable so the unwanted float bits are discarded

  3. Divide the int by the same power of 10 but add use a float form of that (e.g 10.0) so integer gets converted to float and the new value is the correct value

  4. To test, use printf with the precision (.2f)

Srikanth N
  • 137
  • 1
  • 4
  • 1
    Between 1 & 2 should be a preparatory code to cope with rounding. Step 2, effectively truncates the fraction - not round. – chux - Reinstate Monica Feb 27 '18 at 12:39
  • You are correct about truncation and the need for prep code. I assumed the student will write that. Didn't want to provide the complete logic to the student. – Srikanth N Feb 27 '18 at 12:47
0

The two most common methods of rounding are "Away From Zero" and "Banker's Rounding (To Even)".

Pseudo-code for Rounding Away From Zero

EDIT Even though this is pseudo-code, I should have included the accounting for precision, since we are dealing with floating-point values here.

// this code is fixed for 2 decimal places (n = 2) and
// an expected precision limit of 0.001 (m = 3)
// for any values of n and m, the first multiplicand is 10^(n+1)
// the first divisor is 10^(m + 1), and
// the final divisor is 10^(n)

double roundAwayFromZero(double value) {
  boolean check to see if value is a negative number
  add precision bumper of (1.0 / 10000) to "value" // 10000.0 is 10^4
  multiply "value" by 1000.0 and cast to (int)  // 1000.0 is 10^3
  if boolean check is true, negate the integer to positive
  add 5 to integer result, and divide by 10
  if boolean check is true, negate the integer again
  divide the integer by 100.0 and return as double  // 100.0 is 10^2

  ex: -123.456
      true
      -123.456 + (1.0 / 10000.0) => -123.4561
      -123.4561 * 1000.0 => -123456.1 => -123456 as integer
      true, so => -(-123456) => 123456
      (123456 + 5) / 10 => 123461 / 10 => 12346
      true, so => -(12346) => -12346
      -12346 / 100.0 => -123.46 ===> return value
}

In your initial question, you expressed a desire for direction only, not the explicit answer in code. This is as vague as I can manage to make it while still making any sense. I'll leave the "Banker's Rounding" version for you to implement as an exercise.

Mark Benningfield
  • 2,800
  • 9
  • 31
  • 31
0

Ok so I figured it out! thank yall for your answers.

//function
float rounding(float roundedNumber)
{
   roundedNumber = roundedNumber * 100.0f + 0.5f;
   roundedNumber = (int) roundedNumber * 0.01f;

   return roundedNumber;
}

So pretty much if I entered 56.12567 as roundedNumber, it would multiply by 100 yielding 5612.567. From there it would add .5 which would determine if it rounds up. In this case, it does. The number would change to 5613.067. Then you truncate it by converting it into a int and multiply by .01 to get the decimal back over. From there it returns the value to main and prints out the rounded number. Pretty odd way of rounding but I guess thats how you do it in C without using the rounding function.

JacobSedlik19
  • 31
  • 1
  • 2
-1

Well, let's think about it. One thing that's helpful to know is that we can turn a float into an integer by casting:

float x = 5.4;
int y = (int) x;
//y is now equal to 5

When we cast, the float is truncated, meaning that whatever comes after the decimal point is dropped, regardless of its value (i.e. It always rounds towards 0).

So if you think about that and the fact that you care about the hundredths place, you could maybe imagine an approach that consists of manipulating your floating point number in someway such that when you cast it to an int you only truncate information you don't care about (i.e. digits past the hundredths place). Multiplying might be useful here.

John
  • 2,575
  • 1
  • 17
  • 29