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.
The question is:
You are given 2 numbers (N , M); the task is to find N√M (Nth root of M).
Input:
The first line of input contains an integer T denoting the number of test cases. Then T test cases follow. Each test case contains two space separated integers N and M.
Output:
For each test case, in a new line, print an integer denoting Nth root of M if the root is an integer else print -1.
Now my solution to this problem was:
#include <math.h>
#include <iostream>
#include <math.h>
using namespace std;
int main() {
int t;
float x, p;
cin>>t;
for(int i=0;i<t;i++)
{
cin>>p>>x;
if(p==0)
{
cout<<"1"<<endl;
}
else
{
float res=pow(x,(1/p));
cout<<"res="<<res<<endl;
if(res==int(res))
cout<<res<<endl;
else
cout<<"-1"<<endl;
}
}
return 0;
}
This caused a problem in the test case :
1
3
1000
Although when I printed res, I got 10 as a result, during the condition checking if(res==int(res)) turned out to be false.
Also I noticed that changing from float res=pow(x,(1/p)); to float res=pow(x,(1.0/p)); was giving the correct answer. I'm guessing its something related to getting 0.33333 when the evaluation of 1/p is done, but I cannot understand why the printed value is 10 but not matching in the condition checking.
Why are pow(x,1/p) and pow(x,1.0/p) not equal even though printing their values gives the same result (?)
Computations differ due to precision. Computations are not mathematically exact: pow() did not receive an exact 1/3.
With float p, 1/p can differ from 1.0/p as the first is done using float (or wider) math and the second uses double (or wider) as 1.0 is a double.
This in turn calls either a float or double pow(). Thus there are potentially different res results.
In OP's case: pow(1000.0f,(1/3.0f)) performed a float precision calculation something like pow(1000, near_one_third) and not cbrt(1000.0) - the result was not exactly 10.0f. pow(1000.0f,(1.0/3.0f)) performed a like-wise double precision computation that when rounded to float was exactly 10.0f.
why the printed value is 10 but not matching in the condition checking.
Should res have a computed value a wee more or less than 10.0f, then == is not true.
Print with sufficient precision to see differences in the final output. Recommend at least 9 significant digits for float res.
At a minimum, I suggest using the same floating point types and math throughout. (Use 1.0f with float.) Further recommend to use double.
Final outputs may still not be the exact expected integer (from a math analysis) as pow() though.
On x64 Windows using MSVC2013, I am using the cvRound function of OpenCV with the intention of round up from x.5 values. I've come across an inconsistency where cvRound(17.5f) returns 18 (good!), but cvRound(20.5f) returns 20 and not 21 as expected
cvRound is simply implemented thus, so it seems to be an Microsoft inconsistency in _mm_cvtsd_si32().
int cvRound( double value )
{
__m128d t = _mm_set_sd( value );
return _mm_cvtsd_si32(t);
}
Can anyone suggest how/why this could be?
FWIW, cvRound(20.5f + 1e-3f) returns 21.
Small half-integers can be exactly represented by binary floating point -- 0.5 is a power of 2.
What is really going on is "rounding half to even." This is a way to remove a bias which occurs when half-integers are always rounded up.
http://en.wikipedia.org/wiki/Rounding#Round_half_to_even
The rounding behavior of the SSE instructions is configurable via the floating point environment (specifically, the MXCSR register). There are several IEEE rounding modes. The default rounding mode is round-to-nearest, ties-to-even, so if the value is exactly in the middle of two representable values, the result is rounded to the nearest even value.
Consider the following test program that demonstrates the different rounding modes in action:
#include <fenv.h>
#include <immintrin.h>
#include <stdio.h>
int main()
{
printf("Default: %d\n", _mm_cvtsd_si32(_mm_set_sd(20.5)));
fesetround(FE_DOWNWARD);
printf("FE_DOWNWARD: %d\n", _mm_cvtsd_si32(_mm_set_sd(20.5)));
fesetround(FE_UPWARD);
printf("FE_UPWARD: %d\n", _mm_cvtsd_si32(_mm_set_sd(20.5)));
fesetround(FE_TONEAREST);
printf("FE_TONEAREST: %d\n", _mm_cvtsd_si32(_mm_set_sd(20.5)));
fesetround(FE_TOWARDZERO);
printf("FE_TOWARDZERO: %d\n", _mm_cvtsd_si32(_mm_set_sd(20.5)));
}
Output:
Default: 20
FE_DOWNWARD: 20
FE_UPWARD: 21
FE_TONEAREST: 20
FE_TOWARDZERO: 20
The rounding works like that for the same reason that this code prints that the values are equal (tested with MSVC2012)
float f1 = 20.4999999f;
float f2 = 20.5f;
if(f1==f2)
printf("equal\n");
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Hi guys really need your help. There is some problem with my code and i can't figure out whats the error.T
his is my code:
#include<stdio.h>
void main(void)
{
float timeLeavingTP;
int transitNumber;
float transitTime;
printf("Please enter the time leaving TP.\n");
scanf_s("%f",&timeLeavingTP);
printf("Please enter bus number.\n");
scanf_s("%d",&transitNumber);
if(timeLeavingTP==1.00)
{
if(transitNumber==27)
{
printf("The time reached home is 1.54pm.\n");
}
if(transitNumber==8)
{
printf("The time reached home is 1.39pm.\n");
}
if(transitNumber==15)
{
printf("The time reached home is 1.42pm.\n");
}
}
else if(timeLeavingTP==6.30)
{
if(transitNumber==27)
{
printf("The time reached home is 7.32pm");
}
if(transitNumber==8)
{
printf("The time reached home is 7.29pm");
}
if(transitNumber==15)
{
printf("The time reached home is 7.28pm.\n");
}
}
}
After debugging i got
Please enter time leaving TP
1.00
Please enter bus number
27
The time reached home is 1.54pm
Another debugging
Please enter time leaving TP
6.30
Please enter bus number
27
Please enter any key to continue...
May i ask why did the 1.00 work and why the 6.30 do not work. Need your guys help. Thanks a lot!!
This might help you:
http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
You are comparing floating point number for equality which may not work. Also read, the following question:
What is the most effective way for float and double comparison?
This link will also the useful:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
Solution which I suggest in your case is to keep time in integer format (by using 24 hour time format such as 1300 etc) which is in integer and there equality comparison will work.
Also read in C++ FAQs: http://www.parashift.com/c++-faq/floating-point-arith.html
You should avoid using floats for time values like these. A float will only equate a literal, if they are EXACTLY the same. Due to way that a computer stores floating point numbers, they are never exactly what you entered (in this case, it could be stored as 6.30000, which won't be equal to 6.30 to the code).
Since you're not doing anything fancy with the time, I'd suggest reading it in as a string, rather than a float.
try using double instead of float for variables.
double timeLeavingTP;
The values of x and y aren't exactly 0.3 and 0.7, as those numbers aren't representable in binary floating point. It happens that the closest float to 0.3 is greater than the closest double to 0.3, and the closest float to 0.7 is less than the closest double to 0.7... hence your comparison results.
Assuming the representations are the same as in C# (where I happen to have some tools to help) the values involved are:
0.3 as float = 0.300000011920928955078125
0.3 as double = 0.299999999999999988897769753748434595763683319091796875
0.7 as float = 0.699999988079071044921875
0.7 as double = 0.6999999999999999555910790149937383830547332763671875
So that explains why it's happening... but it doesn't explain how to work around the issue for whatever your code is actually trying to do, of course. If you can give more context to the bigger problem, we may be able to help more.
When comparing float to constant you should use extension f
like this:
else if(timeLeavingTP==6.30f)
You really shouldn't use a float for time value. 6.30 is 6:30 or 6:18? what will happen if we add 1.40 to 6.30?
Ok, already a lot of answers. Some additional information:
In C++ standard, section 2.14.14, it is stated that:
The type of a floating literal is double unless explicitly specified by a suffix.
This means that you compare your float variable with a double constant. Unfortunately floating point conversion (float and double) can give very small differences. But the difference is smaller for double which are more precise than for float. This is why your float doesn't match the double.
To avoid this, either use two doubles (see a lot of other responses above), or use two floats, by changing your else if to:
else if (timeLeavingTP == 6.30f)
6.30 looks like a nice simple floating-point number, and in decimal it is, but in binary floating point it is not. 6.30 cannot be represented by a float, and it cannot be represented by a double. It cannot be perfectly represented by any binary floating-point number.
When you write this statement (after assigning 6.30 to timeLeavingTP):
if(timeLeavingTP==6.30)
what you are actually doing is this:
if((float)6.30==(double)6.30)
You are comparing the 32-bit float representation of 6.30 to the 64-bit double representation of 6.30. Both are approximations. The double representation is a closer approximation. Therefore they are not equal.
You could add an epsilon to allow for this slop, but better solutions would be to use 6.30f as your constant (make the right side also a float) or make timeLeavingTP a double. The goal is not to get greater accuracy, but to have consistent accuracy.
See this article for details on this exact problem:
http://randomascii.wordpress.com/2012/06/26/doubles-are-not-floats-so-dont-compare-them/
try this:
#include<stdio.h>
void main(void)
{
float timeLeavingTP;
int transitNumber;
float transitTime;
printf("Please enter the time leaving TP.\n");
scanf_s("%f",&timeLeavingTP);
printf("Please enter bus number.\n");
scanf_s("%d",&transitNumber);
if(timeLeavingTP==1.00)
{
if(transitNumber==27)
{
printf("The time reached home is 1.54pm.\n");
}
if(transitNumber==8)
{
printf("The time reached home is 1.39pm.\n");
}
if(transitNumber==15)
{
printf("The time reached home is 1.42pm.\n");
}
}
if(timeLeavingTP==6.30)
{
if(transitNumber==27)
{
printf("The time reached home is 7.32pm");
}
if(transitNumber==8)
{
printf("The time reached home is 7.29pm");
}
if(transitNumber==15)
{
printf("The time reached home is 7.28pm.\n");
}
}
}
I am accepting an input from user as a float value.
This value can go up to "10 raised to power 18".
The next step involves finding all the divisors of this number. for which i am doing the following:
for(i=2; i<=n/2 ; i++)
{
if(n%i==0)
v.push_back(i);
}
Here, n is the number entered by the user.
Problem is that n is float and using it in if loop index causes it's value to be limited to '10 raised to the power 9'
Hence, is there any way to use data type other than int for using values of range '10 raised to power 18'?
You can use an unsigned long long which is 264 or roughly 1019
This assumes that your compiler supports 64-bit integers.
The question has been answered (use long long int), but wanted to point out that floats are called "floating point" for a reason. They incorporate an exponent, basically the position of the decimal point, which determines the precision of the mantissa. This conveniently allows you to both represent small numbers with high precision and large numbers with low precision, but not both at the same time.
For more details: http://en.wikipedia.org/wiki/IEEE_754-2008
Try this:
int main(void)
{
float i = 16777217.0f;
printf("i = %f\n", i);
i++;
printf("i+1 = %f\n", i);
}
w/ 32-bit floats this returns:
i = 16777216.000000
i+1 = 16777216.000000
So question of the day: what do you think will happen if you have a loop like this?
for(float f; f < 20000000; ++f)
{
// do stuff
}
Sure you can use other data types for loop , use any of the types mentioned here
I think a long double should be substantial.