I am running a program for school and am running into a simple math problem that C is not calculating correctly. I am simply trying to divide my output by a number and it is returning the original number.
int main(void)
{
float fcost = 599;
float shipt = (fcost / 120);
shipt = shipt * 120;
printf("%4.0f", shipt);
return 0;
}
From what was stated in the comments, you want the result of the division to be rounded down.
In order to do that, you should use int instead of float so that integer division is performed (which truncates the fractional part) instead of floating point division (which retains the fractional part):
int fcost = 599;
int shipt = (fcost / 120);
shipt *=120;
printf("%d", shipt);
If you're trying to simply divide the number by 120, remove the next line, i.e remove
shipt*=120
As it nullifies the previous line's process.
In the event this isn't what you mean, please clarify.
OP appears to want a truncated number quotient.
Converting a FP number to int risks undefined behavior (UB) if the original double is much outside the range of int.
The standard library provides various rounding functions to avoid the above problem.
#include <math.h>
int main(void) {
float fcost = 599;
// to round to the next lower whole number
float shipt = floorf(fcost / 120);
// to round to the next higher whole number
float shipt = ceilf(fcost / 120);
// to round to the next whole number toward 0
float shipt = truncf(fcost / 120);
shipt *= 120;
printf("%4.0f", shipt);
return 0;
}
Related
float number = 123.8798831;
number=(floorf((number + number * 0.1) * 100.0)) / 100.0;
printf("number = %f",number);
I want to get number = 136.25
But the compiler shows me number = 136.259995
I know that I can write like this printf("number = %.2f",number) ,but I need the number itself for further operation.It is necessary that the number be stored in a variable as number = 136.25
It is necessary that the number be stored in a variable as number = 136.25
But that would be the incorrect result. The precise result of number + number * 0.1 is 136.26787141. When you round that downwards to 2 decimal places, the number that you would get is 136.26, and not 136.25.
However, there is no way to store 136.26 in a float because it simply isn't a representable value (on your system). Best you can get is a value that is very close to it. You have successfully produced a floating point number that is very close to 136.26. If you cannot accept the slight error in the value, then you shouldn't be using finite precision floating point arithmetic.
If you wish to print the value of a floating point number up to limited number of decimals, you must understand that not all values can be represented by floating point numbers, and that you must use %.2f to get desired output.
Round float to 2 decimal places in C language?
Just like you did:
multiply with 100
round
divide by 100
I agree with the other comments/answers that using floating point numbers for money is usually not a good idea, not all numbers can be stored exactly. Basically, when you use floating point numbers, you sacrifice exactness for being able to storage very large and very small numbers and being able to store decimals. You don't want to sacrifice exactness when dealing with real money, but I think this is a student project, and no actual money is being calculated, so I wrote the small program to show one way of doing this.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void)
{
double number, percent_interest, interest, result, rounded_result;
number = 123.8798831;
percent_interest = 0.1;
interest = (number * percent_interest)/100; //Calculate interest of interest_rate percent.
result = number + interest;
rounded_result = floor(result * 100) / 100;
printf("number=%f, percent_interest=%f, interest=%f, result=%f, rounded_result=%f\n", number, percent_interest, interest, result, rounded_result);
return EXIT_SUCCESS;
}
As you can see, I use double instead float, because double has more precession and floating point constants are of type double not float. The code in your question should give you a warning because in
float number = 123.8798831;
123.8798831 is of type double and has to be converted to float (possibly losing precession in the process).
You should also notice that my program calculates interest at .1% (like you say you want to do) unlike the code in your question which calculates interest at 10%. Your code multiplies by 0.1 which is 10/100 or 10%.
Here is an example of a function you can use for rounding to x number of decimals.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stddef.h>
double dround(double number, int dp)
{
int charsNeeded = 1 + snprintf(NULL, 0, "%.*f", dp, number);
char *buffer = malloc(charsNeeded);
snprintf(buffer, charsNeeded, "%.*f", dp, number);
double result = atof(buffer);
free(buffer);
return result;
}
int main()
{
float number = 37.777779;
number = dround(number,2);
printf("Number is %f\n",number);
return 0;
}
Example (in C):
#include<stdio.h>
int main()
{
int a, b = 999;
float c = 0.0;
scanf("%d", &a);
c = (float)a/b;
printf("%.3lf...", c);
return 0;
}
If I put 998 it will come out 0.999, but I want the result be 0.998; how?
It looks like you want to truncate instead of round.
The mathematical result of 999/998 is 0.9989989989... Rounded to three decimal places, that is 0.999. So if you use %.3f to print it, that's what you're going to get.
When you convert a floating-point number to integer in C, the fractional part is truncated. So if you had the number 998.9989989 and you converted it to an int, you'd get 998. So you can get the result you want by multiplying by 1000, truncating to an int, and dividing by 1000 again:
c = c * 1000;
c = (int)c;
c = c / 1000;
Or you could shorten that to
c = (int)(c * 1000) / 1000.;
This will work fine for problems such as 998/999 ≈ 0.998, but you're close to the edge of where type float's limited precision will start introducing its own rounding issues. Using double would be a better choice. (Type float's limited precision almost always introduces issues.)
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.
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
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
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.
.. 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().
How to round result to third digit after the third digit.
float result = cos(number);
Note that I want to save the result up to the third digit, no rounding. And no, I don't want to print it with .3f, I need to save it as new value;
Example:
0.00367 -> 0.003
N.B. No extra zeroes after 3 are wanted.
Also, I need to be able to get the 3rd digit. For example if it is 0.0037212, I want to get the 3 and use it as an int in some calculation.
0.00367 -> 0.003
A float can typically represent about 232 different values exactly. 0.00367 and 0.003 are not in that set.
The closest float to 0.00367 is 0.0036700000055134296417236328125
The closest float to 0.003__ is 0.0030000000260770320892333984375
I want to save the result up to the third digit
This goal needs a compromise. Save the result to a float near a multiple of 0.001.
Scaling by 1000.0, truncating and dividing by 1000.0 will work for most values.
float y1 = truncf(x * 1000.0f) / 1000.0f;
The above gives a slightly wrong answer with some values near x.xxx000... and x.xxx999.... Using higher precision can solve that.
float y2 = (float) (trunc(x * 1000.0) / 1000.0);
I want to get the 3 and use it as an int in some calculation.
Skip the un-scaling part and only keep 1 digit with fmod().
int digit = (int) fmod((trunc(x * 1000.0), 10);
digit = abs(digit);
In the end, I suspect this approach will not completely satisfy OP's unstated "use it as an int in some calculation.". There are many subtitles to FP math, especially when trying to use a binary FP, as are most double, in some sort of decimal way.
Perhaps the following will meet OP's goal, even though it does some rounding.:
int third_digit = (int) lround(cos(number)*1000.0) % 10;
third_digit = abs(third_digit);
You can scale the value up, use trunc to truncate toward zero, then scale down:
float result = trunc(cos(number) * 1000) / 1000;
Note that due to the inexact nature of floating point numbers, the result won't be the exact value.
If you're looking to specifically extract the third decimal digit, you can do that as follows:
int digit = (int)(result * 1000) % 10;
This will scale the number up so that the digit in question is to the left of the decimal point, then extract that digit.
You can subtract from the number it's remainder from division by 0.001:
result -= fmod(result, 0.001);
Demo
Update:
The question is updated with very conflicting requirements. If you have an exact 0.003 number, there will be infinite numbers of zeroes after it, and it is a mathematical property of numbers. OTOH, float representation cannot guarantee that every exact number of 3 decimal digits will be represented exactly. To solve this problem you will need to give up on using the float type and switch to a some sort of fixed point representation.
Overkill, using sprintf()
double /* or float */ val = 0.00385475337;
if (val < 0) exit(EXIT_FAILURE);
if (val >= 1) exit(EXIT_FAILURE);
char tmp[55];
sprintf(tmp, "%.50f", val);
int third_digit = tmp[4] - '0';
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 8 years ago.
I have the following code:
#include<stdio.h>
int main(int argc, char const *argv[])
{
float min, max, step;
min = -0.85, max = 0.85, step = 0.002;
int rank = 3, total = 4;
float step1 = min + (max - min) * rank / total; // should be 0.425
printf("%f %.7g\n", step1, step1); // 0.425000 0.4250001
float step2 = min + (max - min) * (rank + 1) / total - step; //should be 0.848
printf("%f %.7g\n", step2, step2); // 0.848000 0.848
float noc = (step2 - step1 + step) / step; //should be 212,5
printf("%f %.7g\n", noc, noc); // 212.499985 212.5
int nol = 1200;
int result = (int)nol * noc; //should be 255000
printf("%d\n", result); // 254999
return 0;
}
This is a fragment of code isolated from a project I have to do. The final result should be 255000, but for some causes, it shows 254999. Can someone please explain me what happens in the process? I have read somewhere that multiplying a floating number with 10^k and then dividing back solves such problems, but in this case, due to the variable step varying from 0.000001 to 0.1, I can't actually use that (in the same way, I can't use a defined EPSILON). What else can I do?
Thanks in advance!
P.S.: I have used double and long double as well, but with same problems, only this time error propagates from a further decimal. I am using gcc 4.8.2, under Ubuntu 14.04.1.
Truncation vs. rounding.
Due to subtle rounding effect of FP arithmetic, the product nol * noc may be slightly less than an integer value. Conversion to int results in fractional truncation. Suggest rounding before conversion to int.
#include <math.h>
int result = (int) roundf(nol * noc);
the significant problem(s) are:
1) mixing floating point and double with integer math
--so the compiler promotes all the math to float (or double)
2) not all numbers can be expressed exactly in float
3) --the initialization of min, max, step are taking double literals
and converting them to float
--even double cannot express all values exactly
--some precision is lost when performing the conversion from double to float
4) this code excerpt: (rank + 1) / total is always = 1
--(although the many conversions may result in being 'not exactly' 1)
5) argc and argv are not referenced in your code.
--this, given that all warnings are enabled, will rise two warnings
at compile time about unused parameters
6) this line in your code is not correct syntax
--(although the compiler might not complain) #include<stdio.h>
--it should be #include <stdio.h>
--sometimes spaces count, sometimes they dont