wrong calculation result in Xcode - casting

I have this calculation:
float tempd = 2451545 + 0.0009 + (77.048759/360) + 4682;
NSLog(#"tempd : %f", tempd);
The result using Xcode is : 2456227.250000
But it should be : 2456227.21492
Do you guys have any idea what I'm doing wrong?
I cant seem to figure it out.
Thanks in advance!

Its due to the limitation in the precision of float, try this
double tempd = 2451545 + 0.0009 + (77.048759/360) + 4682;
NSLog(#"tempd : %f", tempd);

Related

C++ different values between variables and debugger

I'm working in C++ with Visual Studio.
I got a strange case. There is my code (simplified version) :
Point GetPoint(/*parameters*/)
{
float Ax = 149; //Value depending on parameters
float Ay = 20;
float Bx = 29;
float By = 19;
double pAB = (Ay - By) / (Ax - Bx);
double Sx = Cx;
double Sy = pAB * (Cx - Ax) + Ay;
// Sy = (20 - 19) / (149 - 29) * (29 - 149) + 20.0
// => Sy = 1 / 120 * -120 + 20
// => Sy = -1 + 20
return new Point(static_cast<int>(Sx), static_cast<int>(Sy));
}
I expected that Sy = 19 but instead my point value is 18. I started the debugger to understand and I found this :
(Ay - By) / (Ax - Bx) = 0.00833333284
(20.0 - 19.0) / (149.0 - 29.0) = 0.0083333333333333332
pAB = 0.0083333337679505348
And :
(20.0 - 19.0) / (149.0 - 29.0) * (29.0 - 149.0) + 20.0 = 19
Sy = 18.999999947845936
Final cast set my point to 18 (sy < 19). But the same code in C# give me a 19. Why theses difference ? And how can I get a 19 ?
C++ and C# are different languages, with different rules and different compilers. Since floating point is inexact by definition, any subtle difference can result in the different values you see.
I don't know the C# rules at all, but in C++, notice that while you have typed pAB as double, you're actually computing its value in float (because Ax, Ay, Bx, By are all floats) and only after that is the value promoted to a double. In other words, you do not gain any precision here by using double. Maybe the C# rules are different here, no idea.
Anyway, if you make sure pAB is computed in double, you get exact values with these particular numbers: [live example], compared to [the unchanged code].
Making sure the double value is actually computed in double is probably the correct solution here. Nevertheless, since floating point is inexact and could "fail" for you with other values, I suggest using std::round instead of casting to int if you want rounding behaviour.

How can i input this formula into my c++ program?

Wind Chill = 35.74 + 0.6215T - 35.75(V^0.16) + 0.4275T(V^0.16)
I need the correct way to input the above formula into my program. I currently have the following and it's giving me a crazy number:
WindChill = ((35.74 + (0.6215 * temperature))
- (35.75 * pow(windSpeed, 0.16))
+ (0.4275 * temperature * pow(windSpeed, 0.16)));
I am a beginner programmer, C++ is my first language I am learning so I would appreciate any and all help. Thank you.
You can simplify by removing parenthesis.
double wind_chill = 35.74 + 0.6215 * T - 35.75 * pow(V, 0.16) + 0.4275 * T * pow(V, 0.16);
But in this case you calculate the power two times. A better way is :
double pow_v = pow(V, 0.16);
double wind_chill = 35.74 + 0.6215 * T - 35.75 * pow_v + 0.4275 * T * pow_v;
Try this. And if you are using your own power function then rather then again and againcalling that method you can store it in some variable. That will be good for efficiency as well as readability.
double windPower = pow(windspeed, 0.16);
WindChill = (35.74 + (0.6215 * temp) - (35.75 * windPower ) + (0.4275 * temp * windPower ))
And your power function ( if you want to define it ) goes like this:-
int pow(int x, unsigned int y)
{
if( y == 0)
return 1;
else if (y%2 == 0)
return power(x, y/2)*power(x, y/2);
else
return x*power(x, y/2)*power(x, y/2);
}
This is for integers ( As I was able to test it quickly ).
If you compute by hand, using the same data, does it give you the same crazy number, or the correct answer? If you get the same crazy number, maybe you need to convert some of your numbers to the correct units, eg temperature should probably be in Kelvin rather than Celsius or Farhenheit.
(This should have been a comment, but I don't have enough rep yet...)

ternary operator default value

I am wondering a bit about the ternary operator mainly in C++ but I think it might apply for other languages as well.
The best example of the problem I am having, (or should I call it a problem? Well a conceptual problem I guess.), would be clamping values.
float clamped = (x<0.3) : 0.3 ? x;
I find myself wanting to write this piece of code, however x might be complex say we have something like this:
float clamped = (1.f - x + my_function()) > .2f ? .2f : (1.f - x + my_function());
This is where it's out of hand in my opinion and I would rewrite it:
float clamped = (1.f - x + my_function());
if (clamped > .2f)
clamped = .2f;
So this leads up to two questions really
1: Is there a defaulting behavior so I could say "do this if true, else just do what it said", in pseudo-code something like: float clamped = (1.f - x + my_function()) > .2f : .2f ? **default**;
2: If I would still do it the first way, will it first evaluate the condition, and if it is false, do another evaluation to get the value from (1.f - x + my_function())?
Hope some of it makes sense, it's something which I haven't gotten around to understand until now.
You can use the max function for this:
float clamped = max(1.f - x + my_function(), .2f);
How about
float v;
float processed = (v = expr) > 0.f ? special_val : v;
?
Or more generically
type tmp;
type result = condition(tmp = expr) ? special_val : tmp;

C++ How do I set the fractional part of a float?

I know how to get the fractional part of a float but I don't know how to set it. I have two integers returned by a function, one holds the integer and the other holds the fractional part.
For example:
int a = 12;
int b = 2; // This can never be 02, 03 etc
float c;
How do I get c to become 12.2? I know I could add something like (float)b \ 10 but then what if b is >= than 10? Then I would have to divide by 100, and so on. Is there a function or something where I can do setfractional(c, b)?
Thanks
edit: The more I think about this problem the more I realize how illogical it is. if b == 1 then it would be 12.1 but if b == 10 it would also be 12.1 so I don't know how I'm going to handle this. I'm guessing the function never returns a number >= 10 for fractional but I don't know.
Something like:
float IntFrac(int integer, int frac)
{
float integer2 = integer;
float frac2 = frac;
float log10 = log10f(frac2 + 1.0f);
float ceil = ceilf(log10);
float pow = powf(10.0f, -ceil);
float res = abs(integer);
res += frac2 * pow;
if (integer < 0)
{
res = -res;
}
return res;
}
Ideone: http://ideone.com/iwG8UO
It's like saying: log10(98 + 1) = log10(99) = 1.995, ceilf(1.995) = 2, powf(10, -2) = 0.01, 99 * 0.01 = 0.99, and then 12 + 0.99 = 12.99 and then we check for the sign.
And let's hope the vagaries of IEEE 754 float math won't hit too hard :-)
I'll add that it would be probably better to use double instead of float. Other than 3d graphics, there are very few fields were using float is a good idea nowadays.
The most trivial method would be counting the digits of b and then divide accordingly:
int i = 10;
while(b > i) // rather slow, there are faster ways
i*= 10;
c = a + static_cast<float>(b)/i;
Note that due to the nature of float the result might not be what you expected. Also, if you want something like 3.004 you can modify the initial value of i to another power of ten.
kindly try this below code after including include math.h and stdlib.h file:
int a=12;
int b=22;
int d=b;
int i=0;
float c;
while(d>0)
{
d/=10;
i++;
}
c=a+(float)b/pow(10,i);

Floats being rounded in C++ and I don't understand why

I am very confused about this... Here is an extract from my code..
float m = 0.0, c = 0.0;
printf("toprightx = %d bottomrightx = %d toprighty = %d bottomrighty = %d\n",
toprightx, bottomrightx, toprighty, bottomrighty);
// find m and c for symmetry line
if (toprightx == bottomrightx) {
m = (-toprighty + bottomrighty);
}
else {
m = (-toprighty + bottomrighty) / (toprightx - bottomrightx);
}
c = -toprighty - (m * toprightx);
printf("m = %f and c = %f\n", m, c);
And here is the output:
toprightx = 241 bottomrightx = 279 toprighty = 174 bottomrighty = 321
m = -3.000000 and c = 549.000000
Why is the output rounding m and c? I have declared them as floats so I don't understand why the code is returning integers. The correct value of m should be -3.8684.
(Note that toprightx, bottomrightx, toprighty, bottomrighty have been declared as integers further up in the code.)
Note that toprightx, bottomrightx, toprighty, bottomrighty have been
declared as integers further up in the code.
There's your answer. Calculations that involve only integers are performed in integer math, including divisions. It doesn't matter that the result is then assigned to a float.
To fix this, either declare at least one of the x/y values as float or cast it to float in the calculation.
You are performing integer division on this line:
(-toprighty + bottomrighty) / (toprightx - bottomrightx);
Since topright, bottomrighty, toprightx, and bottomrightx are all integers, the result of that equation will also be an integer. After the equaition calculates an integer you are assigning it to a float. It is equivalent to:
float m = -3;
You could do something like this instead:
(-toprighty + bottomrighty + 0.0) / (toprightx - bottomrightx);
Here's a hint for you:
m = (-toprighty + bottomrighty) / (toprightx - bottomrightx);
^int ^int ^int ^int
All of those operations will be performed using integer division (truncating floating points) and then cast to float. Try instead:
m = float(-toprighty + bottomrighty) / (toprightx - bottomrightx);
That's because you're using only int's on your calculations, so C++ uses integer calculation for them. Just cast one of your int variables to float and you'll be good.
Changing this statement m = (-toprighty + bottomrighty) / (toprightx - bottomrightx); to m = (-toprighty + bottomrighty) / (float)(toprightx - bottomrightx); will do that.
declare toprightx, bottomrightx, toprighty, bottomrighty as floats or cast them to floats before asking for mixed arithmetic.
Casting(implicitly, as you're doing) a float to an int will truncate the data that won't fit in the new type.
Note that your data isn't being rounded either, it's being truncated.
Try casting the divisor to a floating point number, to force the division to use floating point arithmetic:
m = (-toprighty + bottomrighty) / (float)(toprightx - bottomrightx);