How to properly round up doubles in C? [duplicate] - c

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
For some reason, ceil(x) rounds up round numbers to x+1.
For example:
double og_grade = 50;
double fact_grade = ceil(og_grade*1.1);
og_grade*1.1 should be 55.0000, but ceil(og_grade*1.1) returns 56.0000
Note that og_grade is always a whole number.

I tried the ceil(x) function, but for some reason when x in already
round, it rounds it up to x+1
No that would mean that the implementation of ceil was defective. Not impossible but extremely unlikely.
It's likely that the x for which this effect is observed is in fact not integral, and the decimal portion is omitted from the formatting or debugger.
Assuming IEEE754, the closest double to 1.1 is slightly larger than that; this most likely accounts for your result.
In your case, given that op_grade is in fact a whole number, your best bet is to use an int for op_grade, and multiply by 11 instead; the subsequent rounding checks are then both trivial and exact.

Related

Power function is returning different value in different text editor [duplicate]

This question already has an answer here:
Why the result of pow(10,2) 99 instead of 100? [duplicate]
(1 answer)
Closed last year.
I am trying to use the power function in a program but it is displaying/returning different values in the different text editors. Below is the simple code. I have typecasted since power returns double. In code blocks text editor, the power function is returning 100. But in an atom text editor, it is returning 99. But the same function in atom returns 100 if I replace count by 2. Am I missing installation of any extension in atom?. I don't know what is going on. Any suggestions/corrections are welcome.
#include <stdio.h>
#include <math.h>
int main(){
int count=2;
printf("%d",(int)pow(10,count));
return 0;
}
My guess is that this is due to a floating point rounding error. It may be that, while the real answer is 100, pow(10, 2) is returning 99.99998. When you convert that to an int, the decimal part gets chopped off.
What you can do is, instead of casting right away, run the result through the lround function (also found in math.h). This will return a long.
Avoid the pow function at all cost! It calculates a double raised with a double (for all possible values). This is an extremely complex calculation and it's done using an approximation. Rounding the result instead of using the default double to integer cast (which is defined as "round to zero") helps a bit, but not when the approximation errors more than 0.5.
If you intend to calculate "integer raised with an integer" I strongly suggest that you write your own that simply loops over the exponent -- it's way faster and it doesn't have any approximation problems.
(I say this as someone who has spent 25 years writing C compilers.)

Why is there no output for this program? [duplicate]

This question already has answers here:
Comparing float and double in C
(2 answers)
strange output in comparison of float with float literal
(8 answers)
Closed 1 year ago.
Can someone pls explain me why this is not printing hello?
int main(){
float i;
i=1.2;
while (i==1.2){
printf("hello");
}
Computers only store digital information. Integers can be represented accurately in binary, but floating point numbers are approximated.
It seems that in the approximations, additional tiny values are preventing your exact comparison from being true.
Now is a good time to google "what every programmer should know about floating point numbers" and read it. It will save you countless hours of future programming and debugging if you learn it early.
In addition, there are two floating point types "float" and "double". You are comparing a float to a double, so the approximations of the value are likely not the same approximation, creating more of a chance that the two values won't be equal.

Simple floating point multiplication not giving expected result [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
When given the input 150, I expect the output to be the mathematically correct answer 70685.7750, but I am getting the wrong output 70685.7812.
#include<stdio.h>
int main()
{
float A,n,R;
n=3.14159;
scanf("%f",&R);
A=n*(R*R);
printf("A=%.4f\n",A);
}
float and double numbers are not represented very accurately in the memory. The main reason is that the memory is limited, and most non-integers are not.
The best example is PI. You can specify as many digits as you want, but it will still be an approximation.
The limited precision of representing the numbers is the reason of the following rule:
when working with floats and double numbers, not not check for equality (m == n), but check that the difference between them is smaller than a certain error ((m-n) < e)
Please note, as mentioned in the comments too, that the above rule is not "the mother rule of all rules". There are other rules also.
Careful analysis must be done for each particular situation, in order to have a properly working application.
(Thanks #EricPostpischil for the reminder)
It is common for a variable of type float to be an IEEE-754 32-bit floating point number.
The number 3.14159 cannot be stored exactly in an IEEE-754 32-bit float - the closest value is approximately 3.14159012. 150 * 150 * 3.14159012 is 70685.7777, and the closest value to this that can be represented in a 32-bit float is 70685.78125, which you are then printing with %.4f so you see 70685.7812.
Another way of thinking about this is that your n value only ends up being accurate to the sixth significant figure, so - as you are just calculating a series of multiplications - your result is also only acccurate to the sixth significant figure (ie 70685.8). (In the general case this can be worse - for example subtraction of two close values can lead to a large increase in the relative error).
If you switch to using variables of type double (and change the scanf() to use %lf), then you will likely get the answer you are after. double is typically a 64-bit float, which means that the error in the representation of your n values and the result is small enough not to affect the fourth decimal place.
Have you heard that float and double values aren't always perfectly accurate, have limited precision? Have you heard that type float gives you the equivalent of only about 7 decimal digits' worth of precision? This is what that means. Your expected and actual answers, 70685.7750 and 70685.7812, differ in the seventh digit, just about as expected.
I expect the output to be the mathematically correct answer
I am sorry to disappoint you, but that's your mistake. As a general rule, when you're doing floating-point arithmetic, you will never get the mathematically correct answer, you will always get a limited-precision approximation of the mathematically correct answer.
The canonical SO answers to this sort of question are collected at Is floating point math broken?. You might want to read some of those answers for more enlightenment.

Strange float rounding [duplicate]

This question already has answers here:
Why does division result in zero instead of a decimal?
(5 answers)
Closed 8 years ago.
I'm programming a microcontroller atmega168 (8 bit).
I want to do something like:
float A = cos(- (2/3) * M_PI);
Including of course math.h (#define M_PI 3.14159265358979323846)
As result, instead of having -0.5, i get 1.
I check the result using a serial communication to my pc that i'm sure that works also for float numbers because if i set
A= -0.50;
I receive the correct result.
PS. I cannot use double...also because i don't see the reason of doing so
Help me please!
2/3 is evaluated using integer arithmetic. It evaluates to 0. You mean to use floating point divide
float A = cos(-(2.0/3.0) * M_PI);
If you want float literals use an f suffix:
float A = cos(-(2.0f/3.0f) * M_PI);
Do note however, that the M_PI macro, expanded here, is a double literal. Is that what you want?
I presume the real code doesn't look quite like this. If this really is your code then you would write float A = -0.5f and move on. I guess the real code has variables.
How much precision do you need, and where are the numbers coming from? If your goal is to compute the cosine of 120 degrees, just set a to 0.5. If your original numbers are not expressed as radians, and if you don't need an absolutely precise result, a table-based approximation may be more useful than built in trig functions, since you can strike whatever balance between table size, execution speed, and precision will best fit your needs. Note also that if your original numbers are integers, you may be able to compute trig functions without using any floating-point values [e.g. one could have a function that accepts angles from 0-65535 and returns values from -16384 to +16384]. Integer math is often much faster than floating-point, so such a function could be a major performance win.

How to round a float to particular number of digits after decimal point? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a function to round a float in C or do I need to write my own?
Rounding Number to 2 Decimal Places in C
I am looking for a function in c which could round my float variable to another float variable with two digits after the decimal point, help and demonstrate please.
thank you
Update:
I need this function for calculation purpose, not for printing.
you may try something like this:
float a = 1.234568;
float b = ((int) a*100.f) / 100.f;
instead of (int) you may use floor()/ceil() according to your requirements.

Resources