How can I round a float value (such as 37.777779) to two decimal places (37.78) in C?
If you just want to round the number for output purposes, then the "%.2f" format string is indeed the correct answer. However, if you actually want to round the floating point value for further computation, something like the following works:
#include <math.h>
float val = 37.777779;
float rounded_down = floorf(val * 100) / 100; /* Result: 37.77 */
float nearest = roundf(val * 100) / 100; /* Result: 37.78 */
float rounded_up = ceilf(val * 100) / 100; /* Result: 37.78 */
Notice that there are three different rounding rules you might want to choose: round down (ie, truncate after two decimal places), rounded to nearest, and round up. Usually, you want round to nearest.
As several others have pointed out, due to the quirks of floating point representation, these rounded values may not be exactly the "obvious" decimal values, but they will be very very close.
For much (much!) more information on rounding, and especially on tie-breaking rules for rounding to nearest, see the Wikipedia article on Rounding.
Using %.2f in printf. It only print 2 decimal points.
Example:
printf("%.2f", 37.777779);
Output:
37.77
Assuming you're talking about round the value for printing, then Andrew Coleson and AraK's answer are correct:
printf("%.2f", 37.777779);
But note that if you're aiming to round the number to exactly 37.78 for internal use (eg to compare against another value), then this isn't a good idea, due to the way floating point numbers work: you usually don't want to do equality comparisons for floating point, instead use a target value +/- a sigma value. Or encode the number as a string with a known precision, and compare that.
See the link in Greg Hewgill's answer to a related question, which also covers why you shouldn't use floating point for financial calculations.
How about this:
float value = 37.777779;
float rounded = ((int)(value * 100 + .5) / 100.0);
printf("%.2f", 37.777779);
If you want to write to C-string:
char number[24]; // dummy size, you should take care of the size!
sprintf(number, "%.2f", 37.777779);
Always use the printf family of functions for this. Even if you want to get the value as a float, you're best off using snprintf to get the rounded value as a string and then parsing it back with atof:
#include <math.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
double dround(double val, int dp) {
int charsNeeded = 1 + snprintf(NULL, 0, "%.*f", dp, val);
char *buffer = malloc(charsNeeded);
snprintf(buffer, charsNeeded, "%.*f", dp, val);
double result = atof(buffer);
free(buffer);
return result;
}
I say this because the approach shown by the currently top-voted answer and several others here -
multiplying by 100, rounding to the nearest integer, and then dividing by 100 again - is flawed in two ways:
For some values, it will round in the wrong direction because the multiplication by 100 changes the decimal digit determining the rounding direction from a 4 to a 5 or vice versa, due to the imprecision of floating point numbers
For some values, multiplying and then dividing by 100 doesn't round-trip, meaning that even if no rounding takes place the end result will be wrong
To illustrate the first kind of error - the rounding direction sometimes being wrong - try running this program:
int main(void) {
// This number is EXACTLY representable as a double
double x = 0.01499999999999999944488848768742172978818416595458984375;
printf("x: %.50f\n", x);
double res1 = dround(x, 2);
double res2 = round(100 * x) / 100;
printf("Rounded with snprintf: %.50f\n", res1);
printf("Rounded with round, then divided: %.50f\n", res2);
}
You'll see this output:
x: 0.01499999999999999944488848768742172978818416595459
Rounded with snprintf: 0.01000000000000000020816681711721685132943093776703
Rounded with round, then divided: 0.02000000000000000041633363423443370265886187553406
Note that the value we started with was less than 0.015, and so the mathematically correct answer when rounding it to 2 decimal places is 0.01. Of course, 0.01 is not exactly representable as a double, but we expect our result to be the double nearest to 0.01. Using snprintf gives us that result, but using round(100 * x) / 100 gives us 0.02, which is wrong. Why? Because 100 * x gives us exactly 1.5 as the result. Multiplying by 100 thus changes the correct direction to round in.
To illustrate the second kind of error - the result sometimes being wrong due to * 100 and / 100 not truly being inverses of each other - we can do a similar exercise with a very big number:
int main(void) {
double x = 8631192423766613.0;
printf("x: %.1f\n", x);
double res1 = dround(x, 2);
double res2 = round(100 * x) / 100;
printf("Rounded with snprintf: %.1f\n", res1);
printf("Rounded with round, then divided: %.1f\n", res2);
}
Our number now doesn't even have a fractional part; it's an integer value, just stored with type double. So the result after rounding it should be the same number we started with, right?
If you run the program above, you'll see:
x: 8631192423766613.0
Rounded with snprintf: 8631192423766613.0
Rounded with round, then divided: 8631192423766612.0
Oops. Our snprintf method returns the right result again, but the multiply-then-round-then-divide approach fails. That's because the mathematically correct value of 8631192423766613.0 * 100, 863119242376661300.0, is not exactly representable as a double; the closest value is 863119242376661248.0. When you divide that back by 100, you get 8631192423766612.0 - a different number to the one you started with.
Hopefully that's a sufficient demonstration that using roundf for rounding to a number of decimal places is broken, and that you should use snprintf instead. If that feels like a horrible hack to you, perhaps you'll be reassured by the knowledge that it's basically what CPython does.
Also, if you're using C++, you can just create a function like this:
string prd(const double x, const int decDigits) {
stringstream ss;
ss << fixed;
ss.precision(decDigits); // set # places after decimal
ss << x;
return ss.str();
}
You can then output any double myDouble with n places after the decimal point with code such as this:
std::cout << prd(myDouble,n);
There isn't a way to round a float to another float because the rounded float may not be representable (a limitation of floating-point numbers). For instance, say you round 37.777779 to 37.78, but the nearest representable number is 37.781.
However, you can "round" a float by using a format string function.
You can still use:
float ceilf(float x); // don't forget #include <math.h> and link with -lm.
example:
float valueToRound = 37.777779;
float roundedValue = ceilf(valueToRound * 100) / 100;
In C++ (or in C with C-style casts), you could create the function:
/* Function to control # of decimal places to be output for x */
double showDecimals(const double& x, const int& numDecimals) {
int y=x;
double z=x-y;
double m=pow(10,numDecimals);
double q=z*m;
double r=round(q);
return static_cast<double>(y)+(1.0/m)*r;
}
Then std::cout << showDecimals(37.777779,2); would produce: 37.78.
Obviously you don't really need to create all 5 variables in that function, but I leave them there so you can see the logic. There are probably simpler solutions, but this works well for me--especially since it allows me to adjust the number of digits after the decimal place as I need.
Use float roundf(float x).
"The round functions round their argument to the nearest integer value in floating-point format, rounding halfway cases away from zero, regardless of the current rounding direction." C11dr ยง7.12.9.5
#include <math.h>
float y = roundf(x * 100.0f) / 100.0f;
Depending on your float implementation, numbers that may appear to be half-way are not. as floating-point is typically base-2 oriented. Further, precisely rounding to the nearest 0.01 on all "half-way" cases is most challenging.
void r100(const char *s) {
float x, y;
sscanf(s, "%f", &x);
y = round(x*100.0)/100.0;
printf("%6s %.12e %.12e\n", s, x, y);
}
int main(void) {
r100("1.115");
r100("1.125");
r100("1.135");
return 0;
}
1.115 1.115000009537e+00 1.120000004768e+00
1.125 1.125000000000e+00 1.129999995232e+00
1.135 1.134999990463e+00 1.139999985695e+00
Although "1.115" is "half-way" between 1.11 and 1.12, when converted to float, the value is 1.115000009537... and is no longer "half-way", but closer to 1.12 and rounds to the closest float of 1.120000004768...
"1.125" is "half-way" between 1.12 and 1.13, when converted to float, the value is exactly 1.125 and is "half-way". It rounds toward 1.13 due to ties to even rule and rounds to the closest float of 1.129999995232...
Although "1.135" is "half-way" between 1.13 and 1.14, when converted to float, the value is 1.134999990463... and is no longer "half-way", but closer to 1.13 and rounds to the closest float of 1.129999995232...
If code used
y = roundf(x*100.0f)/100.0f;
Although "1.135" is "half-way" between 1.13 and 1.14, when converted to float, the value is 1.134999990463... and is no longer "half-way", but closer to 1.13 but incorrectly rounds to float of 1.139999985695... due to the more limited precision of float vs. double. This incorrect value may be viewed as correct, depending on coding goals.
Code definition :
#define roundz(x,d) ((floor(((x)*pow(10,d))+.5))/pow(10,d))
Results :
a = 8.000000
sqrt(a) = r = 2.828427
roundz(r,2) = 2.830000
roundz(r,3) = 2.828000
roundz(r,5) = 2.828430
double f_round(double dval, int n)
{
char l_fmtp[32], l_buf[64];
char *p_str;
sprintf (l_fmtp, "%%.%df", n);
if (dval>=0)
sprintf (l_buf, l_fmtp, dval);
else
sprintf (l_buf, l_fmtp, dval);
return ((double)strtod(l_buf, &p_str));
}
Here n is the number of decimals
example:
double d = 100.23456;
printf("%f", f_round(d, 4));// result: 100.2346
printf("%f", f_round(d, 2));// result: 100.23
I made this macro for rounding float numbers.
Add it in your header / being of file
#define ROUNDF(f, c) (((float)((int)((f) * (c))) / (c)))
Here is an example:
float x = ROUNDF(3.141592, 100)
x equals 3.14 :)
Let me first attempt to justify my reason for adding yet another answer to this question. In an ideal world, rounding is not really a big deal. However, in real systems, you may need to contend with several issues that can result in rounding that may not be what you expect. For example, you may be performing financial calculations where final results are rounded and displayed to users as 2 decimal places; these same values are stored with fixed precision in a database that may include more than 2 decimal places (for various reasons; there is no optimal number of places to keep...depends on specific situations each system must support, e.g. tiny items whose prices are fractions of a penny per unit); and, floating point computations performed on values where the results are plus/minus epsilon. I have been confronting these issues and evolving my own strategy over the years. I won't claim that I have faced every scenario or have the best answer, but below is an example of my approach so far that overcomes these issues:
Suppose 6 decimal places is regarded as sufficient precision for calculations on floats/doubles (an arbitrary decision for the specific application), using the following rounding function/method:
double Round(double x, int p)
{
if (x != 0.0) {
return ((floor((fabs(x)*pow(double(10.0),p))+0.5))/pow(double(10.0),p))*(x/fabs(x));
} else {
return 0.0;
}
}
Rounding to 2 decimal places for presentation of a result can be performed as:
double val;
// ...perform calculations on val
String(Round(Round(Round(val,8),6),2));
For val = 6.825, result is 6.83 as expected.
For val = 6.824999, result is 6.82. Here the assumption is that the calculation resulted in exactly 6.824999 and the 7th decimal place is zero.
For val = 6.8249999, result is 6.83. The 7th decimal place being 9 in this case causes the Round(val,6) function to give the expected result. For this case, there could be any number of trailing 9s.
For val = 6.824999499999, result is 6.83. Rounding to the 8th decimal place as a first step, i.e. Round(val,8), takes care of the one nasty case whereby a calculated floating point result calculates to 6.8249995, but is internally represented as 6.824999499999....
Finally, the example from the question...val = 37.777779 results in 37.78.
This approach could be further generalized as:
double val;
// ...perform calculations on val
String(Round(Round(Round(val,N+2),N),2));
where N is precision to be maintained for all intermediate calculations on floats/doubles. This works on negative values as well. I do not know if this approach is mathematically correct for all possibilities.
...or you can do it the old-fashioned way without any libraries:
float a = 37.777779;
int b = a; // b = 37
float c = a - b; // c = 0.777779
c *= 100; // c = 77.777863
int d = c; // d = 77;
a = b + d / (float)100; // a = 37.770000;
That of course if you want to remove the extra information from the number.
this function takes the number and precision and returns the rounded off number
float roundoff(float num,int precision)
{
int temp=(int )(num*pow(10,precision));
int num1=num*pow(10,precision+1);
temp*=10;
temp+=5;
if(num1>=temp)
num1+=10;
num1/=10;
num1*=10;
num=num1/pow(10,precision+1);
return num;
}
it converts the floating point number into int by left shifting the point and checking for the greater than five condition.
Code in question:
std::stringstream cd;
int f = int((15 / allyCounter) * 100);
cd << f;
allyCounter is equal to 45. the idea is to get what percentage 15 is of allyCounter where allyCounter is a dynamic int that is constantly changing. i don't have much experience with c++ so I'm sure what I'm missing is something fundamental.
The problem here is almost certainly with integer vs. floating point math.
15/45 (when done in integer math) is 0.
Try
std::stringstream cd;
int f = int((15.0 / allyCounter) * 100);
cd << f;
...and see if things aren't better. 15.0 is a double precision floating point constant, so that'll force the math to be done in floating point instead of integers, so you'll get a percentage.
Another possibility would be to do the multiplication ahead of the division:
int f = 1500 / allyCounter;
If the numerator were a variable, this could lead to a problem from the numerator overflowing, but in this case we know it's a value that can't overflow.
In C++, 15 / 45 is 0. (It's called "integer division": the result of dividing two ints in C++ is also an int, and thus the real answer is truncated, and 15 / 45 is 0.)
If this is your issue, just make it a double before doing the division:
int f = static_cast<double>(15) / allyCounter * 100;
or even:
int f = 15. / allyCounter * 100;
(The . in 15. causes that to be a double.)
You are using integer division:
std::stringstream cd;
int f = int((15.0 / allyCounter) * 100);
cd << f;
The compiler sees 15/allyCounter and thinks it should return an integer (you passed it two integers, right?). 15/150 == 0 with integer division, you always round down. In this case the compiler sees 15.0 as a double, and uses decimal places.
This is what I've got so far but I can't figure out my next steps.
When I divide my value with 3 I get whole numbers but I want it to display with one decimal and I don't know how.
When that's done I want to round the decimal up or down depending on its value. If it's 3.5 or over it should become 4 and if it's 3.4 or under it should be 3.
void MainWindow::on_pushButton_clicked(){
int paragraph = ui->lineEdit->text().toInt();
int section = ui->lineEdit_2->text().toInt();
int lines = ui->lineEdit_3->text().toInt();
int sum = (paragraph * (lines + 1) -(section * lines));
ui->label_4->setText(QString::number(sum/3));
}
You are dividing integrers and therefore get integer. So fractional part is truncated.
int a = 11;
a = a / 3; // a is 3 now
double b = 11;
b = b / 3; // b is 3.6666... now
double c = a / 3; // c is 3 now
c = b / 3; // c is 3.6666... now
Return type of operators like +, -, * or / is determined by first object in there.
Just use qRound(double(sum)/3.0) or qRound(double(sum)/3) to get rounded value.
If you want to display result with 1 decimal, use QString::number(double(sum)/3.0, 'f', 1).
Please study C basics (read critical parts of K&R) before using C++. And study C++ before using Qt.
If you want to round up and down you can use the C++ math functions ceil and floor. ceil rounds up, and floor rounds down.
For the display you can specify QString::number(sum/3, 'f', 1) which specifies your number, the display format argument (there's an explanation of that here on the QString docs) and then finally sets 2 for the precision.
This question already has answers here:
Why does division result in zero instead of a decimal?
(5 answers)
Closed 9 years ago.
I am trying to do a simple calculation : ( (45/100) - (20+50)/200 )*(10+5)
I am expecting the answer to be 1.5 but when the programme is compiled , it shows 0.
Can someone figure this out for me
#include <iostream>
using namespace std;
int main()
{
float CivIndex = ( (45/100) - (20+50)/200 )
*(10+5);
cout<<CivIndex; // expect 1.5 but getting 0
}
Integer division!
(45 / 100) equals 0 when evaluated as an integer, not 0.45 as you'd been hoping.
Make either numerator or denominator a float to get the expected result:
(45.0 / 100)
What you are doing is integer division, and integer division rounds the result to the closest integer. To correct your code, change it to:
#include <iostream>
using namespace std;
int main()
{
float CivIndex = ( (45.0/100.0) - (20.0+50.0)/200.0 )
*(10.0+5.0);
cout<<CivIndex; // expect 1.5 but getting 0
}
Note: not all .0 are needed, but just put them to be sure.
You are doing integer division.
Specify it as float constants
float CivIndex = ( (45./100) - (20+50)/200. )*(10+5);
^ Notice decimal points^
All your constants are ints, therefore, the compiler is doing integer math. 45/100 as an int is 0. So is 70/200. 0 - 0*15 = 0. You need to tell the compiler that your constants are floats: 20f, or 20.0 would both work. (For each operation, if at least one constant is a float, the operation will be treated as floating point math.)
In C and several other languages diving two integers result in an integer (integral division). That is 45 / 100 in your code will result in 0 instead of the expected 0.45
The fix is simple: convert one of the operands to floating point.
float CivIndex = ( (45/100.0) - (20+50)/200.0 )
*(10+5);
You are hoping the integer division as 0.45 but that is actually 0
Try to change this as:
float CivIndex = ( (45.0/100) - (20.0+50.0)/200 )
*(10+5);
You are essentially evaluating an expression containing only integers. So the
result will be an integer.
You can use casts on the final result of the integer expression.
e.g..
int a=20;float b; b=(float)a;cout<<"b: "<<b;
Please confirm the syntax.
Or as stated above, you can also make one of you operands as a float/double(if your requirement permits).
This question already has answers here:
Precision loss with double C++
(4 answers)
Closed 9 years ago.
So I have the following code
int main(){
double d;
cin>>d;
while(d!=0.00)
{
cout<<d<<endl;
double m = 100*d;
int n = m;
cout<<n<<endl;
cin>>d;
}
return 0;}
When I enter the input 20.40 for d the value of n comes out to be 2039 instead of 2040.
I tried replacing int n = m with int n = (int) m but the result was the same.
Is there any way to fix this. Thanks in advance.
Your code truncates m but you need rounding. Include cmath and use int n = round(m).
Decimal values can, in general, not be represented exactly using binary floating points like double. Thus, the value 20.40 is represented as an approximation which can be used to restore the original value (20.4; the precision cannot be retained), e.g., when formatting the value. Doing computations with these approximated values will typically amplify the error.
As already mentioned in one of the comments, the relevant reference is the paper "What Every Computer Scientist Should Know About Floating-Point Arithmetic". One potential way out of your trouble is to use decimal floating points which are, however, not yet part of the C++ standard.
Single and double presicion floating point numbers are not stored the same way as integers, so whole numbers (e.g. 5, 10) may actually look like long decimals (e.g. 4.9999001, 10.000000001). When you cast to an int, all it does is truncate the whole number. So, if the number is currently represented as 4.999999999, casting it to an int will give you 4. std::round will provide you with a better result most of the time (if the number is 4.6 and you just want the whole number portion, round will not work well). The bigger question is then: what are you hoping to accomplish by casting a double to an int?
In general, when dealing with floating point numbers, you will want to use some epsilon value that is your minimum significant digits. So if you wanted to compare 4.9999999 to 5, you would do (pseudo-code): if abs(5 - 4.9999999) < epsilon, return 5.
Example
int main()
{
double d;
std::cin >> d;
while (std::fabs(d - 0.0) > DBL_EPSILON)
{
std::cout << d << std::endl;
double m = 100 * d;
int n = static_cast<int>(m);
if (std::fabs(static_cast<double>(n) - m) > DBL_EPSILON)
{
n++;
}
std::cout << n << std::endl;
std::cin >> d;
}
return 0;
}
Casting double to int truncates value so 20.40 is probably 20.399999 * 100 is 2039.99 because double is not base 10. You can use round() function that will not truncate but will get you nearest int.
int n = round(m);
Floating point numbers can't exactly represent all decimal numbers, sometimes an approximation is used. In your example the closest possible exact number is 20.39999999999999857891452847979962825775146484375. See IEEE-754 Analysis for a quick way to see exact values.
You can use rounding, but presumably you're really looking for the first two digits truncated. Just add a really small value, e.g. 0.0000000001 before or after you multiply.