I might be missing something very basic here. But I don't know how to figure out that basic thing. When I set T to 10 and dt to 0.1, I should get the result 101 but I am getting the result as 100. Why is it so?
n_sim_steps = (int)(T/dt) + 1
Furthermore, if I execute this as a watch in eclipse, it returns 101, but in code it results in 100.
It should be
n_sim_steps = (int)(T/dt + 0.5) + 1
You are a victim of precission loss
10 / 0.1 may be 99.999999999999 because of this loss and may be casted back to int as 99. Adding 0.5 and then casting would make sure that the result is rounded.
You better to use ceil function.
function signature
double ceil (double x);
like ceil(2.3) will results 3
Related
Currently I have a function in an application which takes in a float as a parameter and should perform a simple multiplication and division on the value passed in. Before the value is passed into the function in the application, it is typecast to a float as the particulars of the main application deal with the numerical data in ints. Unfortunately when I pass in the value of 0.0 to the function, it does not generate an output of 1.0 (which it should from the calculation the function performs) but merely outputs a value of 0.0 and I was wondering why the calulation was failing to produce the correct output as the program compiles and the calculation is correct as far as I'm aware.
Here is the code:
void CarPositionClass::centre(float inputPos)
{
if ((inputPos <= 0) && (inputPos >= -125))
{
membershipC = ((inputPos + 125)*(1 / 125));
}
}
It should also be noted that membershipC is a float variable that is a member of the CarPositionClass.
Change 1 / 125 to, say, 1.0 / 125. 1 / 125 uses integer division, so the result is 0.
Or change this expression
((inputPos + 125)*(1 / 125))
to
(inputPos + 125) / 125
Since inputPos is floating point, so is inputPos + 125, and then dividing a float by an integer is a float.
P.S. This is surely a duplicate question. I expect the C++ gurus to lower the dup hammer any second now. :)
The division between two integers results in an integer. At least one operand has to be a floating point type for it not to truncate the result:
membershipC = ((inputPos + 125)*(1.0 / 125));
// ^^^
Given 2 numbers, where A <= B say for example A = 9 and B = 10, I am trying to get the percentage of how smaller A is compared to B. I need to have the percentage as an int e.g. if the result is 10.00% The int should be 1000.
Here is my code:
int A = 9;
int B = 10;
int percentage = (((1 - (double)A/B) / 0.01)) * 100;
My code returns 999 instead of 1000. Some precision related to the usage of double is lost.
Is there a way to avoid losing precision in my case?
Seems the formula you're looking for is
int result = 10000 - (A*10000+B/2)/B;
The idea is to do all computations in integers and delaying division.
To do the rounding half of the denominator is added before performing the division (otherwise you get truncation in the division and thus upper rounding because of 100%-x)
For example with A=9 and B=11 the percentage is 18.18181818... and rounding 18.18, the computation without the rounding would give 1819 instead of the expected result 1818.
Note that the computation is done all in integers so there is a risk of overflow for large values of A and B. For example if int is 32 bit then A can be up to around 200000 before risking an overflow when computing A*10000.
Using A*10000LL instead of A*10000 in the formula will trade in some speed to raise the limit to a much bigger value.
Offcourse there may be precision loss in floating point number. Either you should use fixed point number as #6502 answered or add a bias to the result to get the intended answer.
You should better do
assert(B != 0);
int percentage = ((A<0) == (B<0) ? 0.5 : -0.5) + (((1 - (double)A/B) / 0.01)) * 100;
Because of precision loss, result of (((1 - (double)A/B) / 0.01)) * 100 may be slightly less or more than intended. If you add extra 0.5, it is guaranteed to be sligthly more than intended. Now when you cast this value to an integer, you get intended answer. (floor or ceil value depending whether the fractional part of the result of equation was above or below 0.5)
I tried
float floatpercent = (((1 - (double)A/B) / 0.01)) * 100;
int percentage = (int) floatpercent;
cout<< percentage;
displays 1000
I suspect a precision loss on automatic casting to int as the root problem to your code.
[I alluded to this in a comment to the original question, but I though I'd post it as an answer.]
The core problem is that the form of expression you're using amplifies the unavoidable floating point loss of precision when representing simple fractions of 10.
Your expression (with casts stripped out for now, using standard precedence to also avoid some parens)
((1 - A/B) / 0.01) * 100
is quite a complicated way of representing what you want, although it's algebraically correct. Unfortunately, floating point numbers can only precisely represent numbers like 1/2, 1/4, 1/8, etc, their multiples, and sums of those. In particular, neither 9/10 or 1/10 or 1/100 have precise representations.
The above expression introduces these errors twice: first in the calculation of A/B, and then in the division by 0.01. These two imprecise values are then divided, which further amplifies the inherent error.
The most direct way to write what you meant (again without needed casts) is
((B-A) / B) * 10000
This produces the correct answer and considerably easier to read, I would suggest, than the original. The fully correct C form is
((B - A) / (double)B) * 10000
I've tested this and it works reliably. As others have noted, it's generally good better to work with doubles instead of floats, as their extra precision makes them less prone (but not immune) to this sort of difficulty.
This question already has answers here:
Error subtracting floating point numbers when passing through 0.0
(4 answers)
Closed 9 years ago.
Consider the following code snippet:
float f = 0.01 ;
printf("%f\n",f - 0.01);
if (f - 0.01 == 0)
{
printf("%f\n",f - 0.01);
}
When I run this code, for the second line I get the output -0.000000, and the if condition does not execute .
What is the reason for the -0.000000?
I remember from a digital logic class I took in college that this arises due to internal representation using one's complement. Please correct me if I'm wrong and please suggest fixes and how to avoid this in the future .
I'm using clang to compile my code , if it matters.
You're running into two problems:
0.01 can't be represented exactly as a binary floating-point value
f has type float while 0.01 has type double
Your calculation requires a conversion from double to float and back which (apparently) isn't giving exactly the same value that it started with.
You might be able to fix this specific example by sticking to a single type (float or double) for all values; but you'll still have problems if you want to compare the results of more complicated calculations for exact equality.
0.01 is a double not a float (You probably have warnings about this when you compile your code.)
So, you're basically converting your "0.01" backwards and forwards between floats and doubles, which is what's causing your discrepancies.
So decide if you want to use floats (e.g 0.01f) or doubles, and stick with one version throughout.
However, as other answers have pointed out, you'll never get an "exact" value when doing floating point arithmetic - it just doesn't work that way.
For reference, both of these versions will give the answer you're expecting
float f = 0.01f ;
printf("%f\n",f - 0.01f);
if (f - 0.01f == 0)
{
printf("%f\n",f - 0.01f);
}
or
double f = 0.01 ;
printf("%f\n",f - 0.01);
if (f - 0.01 == 0)
{
printf("%f\n",f - 0.01);
}
both print
0.000000
0.000000
The reason is that, 0.01 can't be represented correctly in binary floating number. This can be understand by an example: 10/3 is giving the result 3.333333333333333......, i.e it cant be represented correctly in decimal. Similar case with 0.01. Every floating point decimal number can't be represented correctly in binary floating point equivalent.
You have two double 0.01 - one is converted to a float. Due to loss of precision double(float(0.01)) != double(0.01)
Even without the obvious loss of precision you might get into trouble using double(s) only. A compiler might keep one as an extended double in a register and fetch the other from memory (stored as double)
I tried to add two digits with different weights. Here is my code:
void onTimeStepOp::updatePointsType1_2(boost::tuples::tuple<float,int,int,int> &_prev,
boost::tuples::tuple<float,int,int,int> &_result,
boost::tuples::tuple<float,float> weights)
{
_result.get<0>() = _result.get<0>() * weights.get<0>() + _prev.get<0>() * weights.get<1>();
std::cout<<"deb:"<<(float)_result.get<2>() * weights.get<0>()<<" "<<(float)_prev.get<2>() * weights.get<1>()<<std::endl;
_result.get<2>() = (int)((float)(_result.get<2>()) * weights.get<0>() + (float)(_prev.get<2>()) * weights.get<1>());
std::cout<<"deb2:"<<(float)_result.get<3>() * weights.get<0>() <<" "<< (float)_prev.get<3>() * weights.get<1>()<<std::endl;
_result.get<3>() = (int)((float)(_result.get<3>()) * weights.get<0>() + (float)(_prev.get<3>()) * weights.get<1>());
}
weights.get<0> = 0.3,weights.get<1> = 0.7.
The output I get looks like this:
resultBefore=36.8055 4 69 91 previousPPos=41.192 4 69 91
deb:20.7 48.3
deb2:27.3 63.7
resultAfter=39.8761 4 **68** 91
The third number should be 69(69 * 0.3 + 69 * 0.7). However, it is 68 instead. What's the problem with the type conversion expression?
Conversion to int truncates, so the slightest rounding error could cause you to be one off. Rather than converting directly to int, you might want to use the function round.
I might add that weights.get<0> is certainly not 0.3, and weights.get<1> is certainly not 0.7, since neither 0.3 nor 0.7 are representable in machine floating point (at least not on any machine you're likely to be using).
You should round() instead of just casting to int. Casting trims everything after the decimal point, and the number due to rounding error may be something like 68.99999999991 (just an example but gives the idea).
Casting to int will result the number before the dot, so 68.1..68.9 will be all 68 as written before.
Another solution could be, which is not so nice, that is to add 0.5 to your float value before casting. So 68.1 will be 68.6, which will be still 68, but 68.5 will be 69 which will be 69.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Division in C++ not working as expected
Turns out my program has been returning wrong results, so I decided to break the code into little pieces. After setting breakpoint, turns out that...
double test3 = ((2 - 1) / 2);
...equals 0 according to C++ compiler. I have no idea why. Can someone explain it to me?
I'm using MS Visual Studio Premium 2012
Because you are doing integer division. 1/2 is 0, which is then converted to double, yielding 0.. If you want floating point division, try making one of the arguments of the division a floating point number:
double test3 = (2.0-1)/2;
Because the numbers you used on the right hand side are all integers: (i.e.: the expression (2-1)/2 evaluates to 0 as (int)1/(int)2 evaluates to 0 since the whole thing is an integer.
Change it to:
double test3 = ((2 - 1) / 2.0);
And the expression is then (int)1/(double)2, which will evaluate to a double, and thus 0.5
When only integers are involved in an expression, you will only get integer arithmetic. If you want to have floating point arithmetic, you need to involve a floating point expression at some point, e.g.
double test3 = ((2 - 1) / 2.0);
try making your numbers double, (2.-1.)/2.;