Rounding function in C - c

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

Related

Round 37.1-28.75 float calculation correctly to 8.4 instead of 8.3

I have problem with floating point rounding. I want to calculate floating point numbers and round them to (given) N decimals. In this example I want to round to 1 decimal places.
Calculation 37.1-28.75 will result into floating point 8.349998 (instead of 8.35), which will result printf rounding to 8.3 instead of 8.4 for 1 decimal places.
The actual result in math is 37.10-28.75=8.35000000, but due to floating point imprecision it is converted into 8.349998, which is then converted into 8.3 instead of 8.4 when using 1 decimal place rounding.
Minimum reproducible example:
float a = 37.10;
float b = 28.75;
//a-b = 8.35 = 8.4
printf("%.1f\n", a - b); //outputs 8.3 instead of 8.4
Is it valid to add following to the result:
float result = a - b;
if (result > 0.0f)
{
result += powf(10, -nr_of_decimals - 1) / 2;
}
else
{
result -= powf(10, -nr_of_decimals - 1) / 2;
}
EDIT: corrected that I want 1 decimal place rounded output, not 2 decimal places
EDIT2: negative results are needed as well (28.75-37.1 = -8.4)
On my system I do actually get 8.35. It's possible that you have to set the rounding direction to "nearest" first, try this (compile with e.g. gcc ... -lm):
#include <fenv.h>
#include <stdio.h>
int main()
{
float a = 37.10;
float b = 28.75;
float res = a - b;
fesetround(FE_TONEAREST);
printf("%.2f\n", res);
}
Binary floating point is, after all, binary, and if you do care about the correct decimal rounding this much, then your choices would be:
decimal floating point, or
fixed point.
I'd say the solution is to use fixed point, especially if you're on embedded, and forget about everything else.
With
int32_t a = 3710;
int32_t b = 2875;
the result of
a - b
will exactly be
835
every time; and then you just need to have a simple fixed point printing routine for the desired precision, and check the following digit after the last digit to see if it needs to be rounded up.
If you want to round to 2 decimals, you can add 0.005 to the result and then offset it with floorf:
float f = 37.10f - 28.75f;
float r = floorf((f + 0.005f) * 100.f) / 100.f;
printf("%f\n", r);
The output is 8.350000
Why are you using floats instead of doubles?
Regarding your question:
Is it valid to add following to the result:
float result = a - b;
if (result > 0.0f)
{
result += powf(10, -nr_of_decimals - 1) / 2;
}
else
{
result -= powf(10, -nr_of_decimals - 1) / 2;
}
It doesn't seem so, on my computer I get 8.350498 instead of 8.350000.
After your edit:
Calculation 37.1-28.75 will result into floating point 8.349998, which will result printf rounding to 8.3 instead of 8.4.
Then
float r = roundf((f + (f < 0.f ? -0.05f : +0.05f)) * 10.f) / 10.f;
is what you are looking for.

Alternative to ceil() and floor() to get the closest integer values, above and below of a floating point value?

I´m looking for an alternative for the ceil() and floor() functions in C, due to I am not allowed to use these in a project.
What I have build so far is a tricky back and forth way by the use of the cast operator and with that the conversion from a floating-point value (in my case a double) into an int and later as I need the closest integers, above and below the given floating-point value, to be also double values, back to double:
#include <stdio.h>
int main(void) {
double original = 124.576;
double floorint;
double ceilint;
int f;
int c;
f = (int)original; //Truncation to closest floor integer value
c = f + 1;
floorint = (double)f;
ceilint = (double)c;
printf("Original Value: %lf, Floor Int: %lf , Ceil Int: %lf", original, floorint, ceilint);
}
Output:
Original Value: 124.576000, Floor Int: 124.000000 , Ceil Int: 125.000000
For this example normally I would not need the ceil and floor integer values of c and f to be converted back to double but I need them in double in my real program. Consider that as a requirement for the task.
Although the output is giving the desired values and seems right so far, I´m still in concern if this method is really that right and appropriate or, to say it more clearly, if this method does bring any bad behavior or issue into the program or gives me a performance-loss in comparison to other alternatives, if there are any other possible alternatives.
Do you know a better alternative? And if so, why this one should be better?
Thank you very much.
Do you know a better alternative? And if so, why this one should be better?
OP'code fails:
original is already a whole number.
original is a negative like -1.5. Truncation is not floor there.
original is just outside int range.
original is not-a-number.
Alternative construction
double my_ceil(double x)
Using the cast to some integer type trick is a problem when x is outsize the integer range. So check first if x is inside range of a wide enough integer (one whose precision exceeds double). x values outside that are already whole numbers. Recommend to go for the widest integer (u)intmax_t.
Remember that a cast to an integer is a round toward 0 and not a floor. Different handling needed if x is negative/positive when code is ceil() or floor(). OP's code missed this.
I'd avoid if (x >= INTMAX_MAX) { as that involves (double) INTMAX_MAX whose rounding and then precise value is "chosen in an implementation-defined manner". Instead, I'd compare against INTMAX_MAX_P1. some_integer_MAX is a Mersenne Number and with 2's complement, ...MIN is a negated "power of 2".
#include <inttypes.h>
#define INTMAX_MAX_P1 ((INTMAX_MAX/2 + 1)*2.0)
double my_ceil(double x) {
if (x >= INTMAX_MAX_P1) {
return x;
}
if (x < INTMAX_MIN) {
return x;
}
intmax_t i = (intmax_t) x; // this rounds towards 0
if (i < 0 || x == i) return i; // negative x is already rounded up.
return i + 1.0;
}
As x may be a not-a-number, it is more useful to reverse the compare as relational compare of a NaN is false.
double my_ceil(double x) {
if (x >= INTMAX_MIN && x < INTMAX_MAX_P1) {
intmax_t i = (intmax_t) x; // this rounds towards 0
if (i < 0 || x == i) return i; // negative x is already rounded up.
return i + 1.0;
}
return x;
}
double my_floor(double x) {
if (x >= INTMAX_MIN && x < INTMAX_MAX_P1) {
intmax_t i = (intmax_t) x; // this rounds towards 0
if (i > 0 || x == i) return i; // positive x is already rounded down.
return i - 1.0;
}
return x;
}
You're missing an important step: you need to check if the number is already integral, so for ceil assuming non-negative numbers (generalisation is trivial), use something like
double ceil(double f){
if (f >= LLONG_MAX){
// f will be integral unless you have a really funky platform
return f;
} else {
long long i = f;
return 0.0 + i + (f != i); // to obviate potential long long overflow
}
}
Another missing piece in the puzzle, which is covered off by my enclosing if, is to check if f is within the bounds of a long long. On common platforms if f was outside the bounds of a long long then it would be integral anyway.
Note that floor is trivial due to the fact that truncation to long long is always towards zero.

taylor series with error at most 10^-3

I'm trying to calculate the the taylor series of cos(x) with error at most 10^-3 and for all x ∈ [-pi/4, pi/4], that means my error needs to be less than 0.001. I can modify the x +=in the for loop to have different result. I tried several numbers but it never turns to an error less than 0.001.
#include <stdio.h>
#include <math.h>
float cosine(float x, int j)
{
float val = 1;
for (int k = j - 1; k >= 0; --k)
val = 1 - x*x/(2*k+2)/(2*k+1)*val;
return val;
}
int main( void )
{
for( double x = 0; x <= PI/4; x += 0.9999 )
{
if(cosine(x, 2) <= 0.001)
{
printf("cos(x) : %10g %10g %10g\n", x, cos(x), cosine(x, 2));
}
printf("cos(x) : %10g %10g %10g\n", x, cos(x), cosine(x, 2));
}
return 0;
}
I'm also doing this for e^x too. For this part, x must in [-2,2] .
float exponential(int n, float x)
{
float sum = 1.0f; // initialize sum of series
for (int i = n - 1; i > 0; --i )
sum = 1 + x * sum / i;
return sum;
}
int main( void )
{
// change the number of x in for loop so you can have different range
for( float x = -2.0f; x <= 2.0f; x += 1.587 )
{
// change the frist parameter to have different n value
if(exponential(5, x) <= 0.001)
{
printf("e^x = %f\n", exponential(5, x));
}
printf("e^x = %f\n", exponential(5, x));
}
return 0;
}
But whenever I changed the number of terms in the for loop, it always have an error that is greater than 1. How am I suppose to change it to have errors less than 10^-3?
Thanks!
My understanding is that to increase precision, you would need to consider more terms in the Taylor series. For example, consider what happens when
you attempt to calculate e(1) by a Taylor series.
$e(x) = \sum\limits_{n=0}^{\infty} frac{x^n}{n!}$
we can consider the first few terms in the expansion of e(1):
n value of nth term sum
0 x^0/0! = 1 1
1 x^1/1! = 1 2
2 x^2/2! = 0.5 2.5
3 x^3/3! = 0.16667 2.66667
4 x^4/4! = 0.04167 2.70834
You should notice two things, first that as we add more terms we are getting closer to the exact value of e(1), also that the difference between consecutive sums are getting smaller.
So, an implementation of e(x) could be written as:
#include <stdbool.h>
#include <stdio.h>
#include <math.h>
typedef float (*term)(int, int);
float evalSum(int, int, int, term);
float expTerm(int, int);
int fact(int);
int mypow(int, int);
bool sgn(float);
const int maxTerm = 10; // number of terms to evaluate in series
const float epsilon = 0.001; // the accepted error
int main(void)
{
// change these values to modify the range and increment
float start = -2;
float end = 2;
float inc = 1;
for(int x = start; x <= end; x += inc)
{
float value = 0;
float prev = 0;
for(int ndx = 0; ndx < maxTerm; ndx++)
{
value = evalSum(0, ndx, x, expTerm);
float diff = fabs(value-prev);
if((sgn(value) && sgn(prev)) && (diff < epsilon))
break;
else
prev = value;
}
printf("the approximate value of exp(%d) is %f\n", x, value);
}
return 0;
}
I've used as a guess that we will not need to use more then ten terms in the expansion to get to the desired precision, thus the inner for loop is where we loop over values of n in the range [0,10].
Also, we have several lines dedicated to checking if we reach the required precision. First I calculate the absolute value of the difference between the current evaluation and the previous evaluation, and take the absolute difference. Checking if the difference is less than our epsilon value (1E-3) is on of the criteria to exit the loop early. I also needed to check that the sign of of the current and the previous values were the same due to some fluctuation in calculating the value of e(-1), that is what the first clause in the conditional is doing.
float evalSum(int start, int end, int val, term fnct)
{
float sum = 0;
for(int n = start; n <= end; n++)
{
sum += fnct(n, val);
}
return sum;
}
This is a utility function that I wrote to evaluate the first n-terms of a series. start is the starting value (which is this code always 0), and end is the ending value. The final parameter is a pointer to a function that represents how to calculate a given term. In this code, fnct can be a pointer to any function that takes to integer parameters and returns a float.
float expTerm(int n, int x)
{
return (float)mypow(x,n)/(float)fact(n);
}
Buried down in this one-line function is where most of the work happens. This function represents the closed form of a Taylor expansion for e(n). Looking carefully at the above, you should be able to see that we are calculating $\fract{x^n}{n!}$ for a given value of x and n. As a hint, for doing the cosine part you would need to create a function to evaluate the closed for a term in the Taylor expansion of cos. This is given by $(-1)^n\fact{x^{2n}}{(2n)!}$.
int fact(int n)
{
if(0 == n)
return 1; // by defination
else if(1 == n)
return 1;
else
return n*fact(n-1);
}
This is just a standard implementation of the factorial function. Nothing special to see here.
int mypow(int base, int exp)
{
int result = 1;
while(exp)
{
if(exp&1) // b&1 quick check for odd power
{
result *= base;
}
exp >>=1; // exp >>= 1 quick division by 2
base *= base;
}
return result;
}
A custom function for doing exponentiation. We certainly could have used the version from <math.h>, but because I knew we would only be doing integer powers we could write an optimized version. Hint: in doing cosine you probably will need to use the version from <math.h> to work with floating point bases.
bool sgn(float x)
{
if(x < 0) return false;
else return true;
}
An incredibly simple function to determine the sign of a floating point value, returning true is positive and false otherwise.
This code was compiled on my Ubuntu-14.04 using gcc version 4.8.4:
******#crossbow:~/personal/projects$ gcc -std=c99 -pedantic -Wall series.c -o series
******#crossbow:~/personal/projects$ ./series
the approximate value of exp(-2) is 0.135097
the approximate value of exp(-1) is 0.367857
the approximate value of exp(0) is 1.000000
the approximate value of exp(1) is 2.718254
the approximate value of exp(2) is 7.388713
The expected values, as given by using bc are:
******#crossbow:~$ bc -l
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
e(-2)
.13533528323661269189
e(-1)
.36787944117144232159
e(0)
1.00000000000000000000
e(1)
2.71828182845904523536
e(2)
7.38905609893065022723
As you can see, the values are well within the tolerances that you requests. I leave it as an exercise to do the cosine part.
Hope this helps,
-T
exp and cos have power series that converge everywhere on the real line. For any bounded interval, e.g. [-pi/4, pi/4] or [-2, 2], the power series converge not just pointwise, but uniformly to exp and cos.
Pointwise convergence means that for any x in the region, and any epsilon > 0, you can pick a large enough N so that the approximation you get from the first N terms of the taylor series is within epsilon of the true value. However, with pointwise convergence, the N may be small for some x's and large for others, and since there are infinitely many x's there may be no finite N that accommodates them all. For some functions that really is what happens sometimes.
Uniform convergence means that for any epsilon > 0, you can pick a large enough N so that the approximation is within epsilon for EVERY x in the region. That's the kind of approximation that you are looking for, and you are guaranteed that that's the kind of convergence that you have.
In principle you could look at one of the proofs that exp, cos are uniformly convergent on any finite domain, sit down and say "what if we take epsilon = .001, and the regions to be ...", and compute some finite bound on N using a pen and paper. However most of these proofs will use at some steps some estimates that aren't sharp, so the value of N that you compute will be larger than necessary -- maybe a lot larger. It would be simpler to just implement it for N being a variable, then check the values using a for-loop like you did in your code, and see how large you have to make it so that the error is less than .001 everywhere.
So, I can't tell what the right value of N you need to pick is, but the math guarantees that if you keep trying larger values eventually you will find one that works.

How do I write only the decimal places in C language?

If I have 2.55, how do I write only .55 and skip 2 in programming language?
Well you can do this to store it in another variable -
double a=2.55,b;
b =a-(long)a; // subtracting decimal part from a
printf("%.2f\n",b);
As pointed out by Mark Dickinson Sir in comment that this is not safe . So you can make use of function modf from <math.h>-
For example -
double a=-2.55,b,i;
b =modf(a,&i); // i will give integer part and b will give fraction part
printf("%.2f\n",b);
Use double modf(double value, double *iptr) to get the factional part. Use round() to get the best value near the requested precision.
double GetDecimalPlaces(double x, unsigned places) {
double ipart;
double fraction = modf(x, &ipart);
return fraction;
// or
double scale = pow(10.0, places);
return round(fraction * scale)/scale;
}
void GetDecimalPlaces_Test(double x, unsigned places) {
printf("x:%e places:%u -->", x, places);
printf("%#.*f\n", places, GetDecimalPlaces(x, places));
// Additional work needed if leading '0' is not desired.
}
int main(void) {
GetDecimalPlaces_Test(2.55, 2);
GetDecimalPlaces_Test(-2.55, 2);
GetDecimalPlaces_Test(2.05, 2);
GetDecimalPlaces_Test(0.0, 2);
GetDecimalPlaces_Test(0.0005, 2);
}
Output
x:2.550000e+00 places:2 -->0.55
x:-2.550000e+00 places:2 -->-0.55
x:2.050000e+00 places:2 -->0.05
x:0.000000e+00 places:2 -->0.00
x:5.000000e-04 places:2 -->0.00
One dirty trick is to cast your double to an int to get only the whole number. You can then subtract the two to get only the decimal part:
double d = 2.55;
double remainder = d - (int)d;
printf ("%.2f\n", remainder);
double values are not perfectly precise, so small rounding errors can get introduced. You can store the total number in an Integer. You can for example divide by 100 to get the value before the . and use % modulus to get the decimal values.
Example:
int main()
{
int num = 255;
printf("%d.%d\n", num / 100, num % 100); // prints 2.55
printf(".%d", num % 100); // prints .55
return 0;
}
This fails with negative numbers, but you can easily add cases to handle that.

Is there a function to round a float in C or do I need to write my own?

Is there a function to round a float in C or do I need to write my own?
float conver = 45.592346543;
I would like to round the actual value to one decimal place, conver = 45.6.
As Rob mentioned, you probably just want to print the float to 1 decimal place. In this case, you can do something like the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
return 0;
}
If you want to actually round the stored value, that's a little more complicated. For one, your one-decimal-place representation will rarely have an exact analog in floating-point. If you just want to get as close as possible, something like this might do the trick:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
conver = conver*10.0f;
conver = (conver > (floor(conver)+0.5f)) ? ceil(conver) : floor(conver);
conver = conver/10.0f;
//If you're using C99 or better, rather than ANSI C/C89/C90, the following will also work.
//conver = roundf(conver*10.0f)/10.0f;
printf("conver is now %f\n",conver);
return 0;
}
I doubt this second example is what you're looking for, but I included it for completeness. If you do require representing your numbers in this way internally, and not just on output, consider using a fixed-point representation instead.
Sure, you can use roundf(). If you want to round to one decimal, then you could do something like: roundf(10 * x) / 10
#include <math.h>
double round(double x);
float roundf(float x);
Don't forget to link with -lm. See also ceil(), floor() and trunc().
Just to generalize Rob's answer a little, if you're not doing it on output, you can still use the same interface with sprintf().
I think there is another way to do it, though. You can try ceil() and floor() to round up and down. A nice trick is to add 0.5, so anything over 0.5 rounds up but anything under it rounds down. ceil() and floor() only work on doubles though.
EDIT: Also, for floats, you can use truncf() to truncate floats. The same +0.5 trick should work to do accurate rounding.
To print a rounded value, #Matt J well answers the question.
float x = 45.592346543;
printf("%0.1f\n", x); // 45.6
As most floating point (FP) is binary based, exact rounding to one decimal place is not possible when the mathematically correct answer is x.1, x.2, ....
To convert the FP number to the nearest 0.1 is another matter.
Overflow: Approaches that first scale by 10 (or 100, 1000, etc) may overflow for large x.
float round_tenth1(float x) {
x = x * 10.0f;
...
}
Double rounding: Adding 0.5f and then using floorf(x*10.0f + 0.5f)/10.0 returns the wrong result when the intermediate sum x*10.0f + 0.5f rounds up to a new integer.
// Fails to round 838860.4375 correctly, comes up with 838860.5
// 0.4499999880790710449 fails as it rounds to 0.5
float round_tenth2(float x) {
if (x < 0.0) {
return ceilf(x*10.0f + 0.5f)/10.0f;
}
return floorf(x*10.0f + 0.5f)/10.0f;
}
Casting to int has the obvious problem when float x is much greater than INT_MAX.
Using roundf() and family, available in <math.h> is the best approach.
float round_tenthA(float x) {
double x10 = 10.0 * x;
return (float) (round(x10)/10.0);
}
To avoid using double, simply test if the number needs rounding.
float round_tenthB(float x) {
const float limit = 1.0/FLT_EPSILON;
if (fabsf(x) < limit) {
return roundf(x*10.0f)/10.0f;
}
return x;
}
There is a round() function, also fround(), which will round to the nearest integer expressed as a double. But that is not what you want.
I had the same problem and wrote this:
#include <math.h>
double db_round(double value, int nsig)
/* ===============
**
** Rounds double <value> to <nsig> significant figures. Always rounds
** away from zero, so -2.6 to 1 sig fig will become -3.0.
**
** <nsig> should be in the range 1 - 15
*/
{
double a, b;
long long i;
int neg = 0;
if(!value) return value;
if(value < 0.0)
{
value = -value;
neg = 1;
}
i = nsig - log10(value);
if(i) a = pow(10.0, (double)i);
else a = 1.0;
b = value * a;
i = b + 0.5;
value = i / a;
return neg ? -value : value;
}
you can use #define round(a) (int) (a+0.5) as macro
so whenever you write round(1.6) it returns 2 and whenever you write round(1.3) it return 1.

Resources