|
Ben_Hurr
|
 |
« on: March 09, 2012, 11:03:23 AM » |
|
x is a float. xvel is a float. x is 111.599998. xvel is 0.400000006. x + xvel equals 112.0. Int(x + xvel) equals 111. (cast to INT) Why do they not equal the same value?  Did I just run into a limited percision bug? Is INT() casting both numbers as INT then adding them together? SO MANY QUESTIONS!
|
|
|
|
|
Logged
|
|
|
|
|
Geeze
|
 |
« Reply #1 on: March 09, 2012, 11:46:59 AM » |
|
x is a float. xvel is a float. x is 111.599998. xvel is 0.400000006. x + xvel equals 112.0. Int(x + xvel) equals 111. (cast to INT) Why do they not equal the same value?  Did I just run into a limited percision bug? Is INT() casting both numbers as INT then adding them together? SO MANY QUESTIONS! So x + xvel is 119.999998006? My guess is rounding.
|
|
|
|
|
Logged
|
|
|
|
|
mcc
|
 |
« Reply #2 on: March 09, 2012, 12:05:56 PM » |
|
Floating point calculations are approximate and as geeze says your printout function is probably rounding to significant digits. Use roundf().
|
|
|
|
|
Logged
|
|
|
|
|
Ben_Hurr
|
 |
« Reply #3 on: March 09, 2012, 12:35:39 PM » |
|
Well, it's not my print function because this bug is breaking my collision engine.
Also, I've tried putting the results of (x+xvel) into another float variable, then casting that variable in the actual equation, and it works as expected. Weird.
Mind you I'm working in BlitzMax, so there is no Print() vs Printf().
|
|
|
|
|
Logged
|
|
|
|
|
ham and brie
|
 |
« Reply #4 on: March 09, 2012, 12:36:44 PM » |
|
Is INT() casting both numbers as INT then adding them together?
Actually I think it'll be doing it at higher precision, getting an answer that's just short of 112, before casting it to 111. This can be affected by exactly how the program was compiled and control flags that can be changed at run time.
|
|
|
|
|
Logged
|
|
|
|
|
wademcgillis
Guest
|
 |
« Reply #5 on: March 09, 2012, 12:50:45 PM » |
|
This thread made my day. 
|
|
|
|
|
Logged
|
|
|
|
|
Ben_Hurr
|
 |
« Reply #6 on: March 09, 2012, 12:51:08 PM » |
|
Yay, time to switch to Integers for fractional numbers.  It's not even that Floats and Doubles are inaccurate, its that I'm getting a different result despite using the same variables in the same way but written differently. 
|
|
|
|
« Last Edit: March 09, 2012, 01:08:36 PM by Ben_Hurr »
|
Logged
|
|
|
|
|
powly
|
 |
« Reply #7 on: March 09, 2012, 01:25:00 PM » |
|
... 
|
|
|
|
|
Logged
|
|
|
|
|
Ben_Hurr
|
 |
« Reply #8 on: March 09, 2012, 01:49:00 PM » |
|
 And then you convert all the Floats to Doubles, and get 111.9~  I'm starting to hate floating point numbers.
|
|
|
|
|
Logged
|
|
|
|
|
powly
|
 |
« Reply #9 on: March 09, 2012, 02:04:45 PM » |
|
It looks as if the Int() function of your runtime (blitzmax?) does the rounding first and the sum afterwards (as you seem to have already suggested, I once again did a good job reading the topic carefully). Pretty unfortunate, but would it work if you had Int(Float(x+xvel))?
|
|
|
|
|
Logged
|
|
|
|
|
Ben_Hurr
|
 |
« Reply #10 on: March 09, 2012, 02:12:20 PM » |
|
Nope.
Maybe theres a better way to do this. All I'm trying to find out in this specific situation is if we increased (or decreased) to a different grid position.
|
|
|
|
|
Logged
|
|
|
|
|
powly
|
 |
« Reply #11 on: March 09, 2012, 02:19:04 PM » |
|
Something like "if newpos>=ceil(oldpos) then" increased, "if newpos<floor(oldpos) then" decreased? Or you could try using intermediate values, if they round properly, and rounding them down.
|
|
|
|
|
Logged
|
|
|
|
|
Ben_Hurr
|
 |
« Reply #12 on: March 09, 2012, 02:34:38 PM » |
|
I fixed by using an intermediary variable. It still feels gross and hacky though. 
|
|
|
|
|
Logged
|
|
|
|
|
Belimoth
|
 |
« Reply #13 on: March 09, 2012, 02:41:26 PM » |
|
Int() rounds towards zero... not very useful if you ask me. As far as "x + xvel = 112" it doesn't actually. That's significant digits at work, not rounding. sum:Float = x + xvel Print sum sum = sum - xvel Print sum
|
|
|
|
|
Logged
|
|
|
|
|
ham and brie
|
 |
« Reply #14 on: March 09, 2012, 04:19:22 PM » |
|
As far as "x + xvel = 112" it doesn't actually.
Actually sometimes it can be 112. As I said above, it can depend on exactly how a program is compiled and even on the flags which can change at run time which control the internal precision at which calculations are done and how they are rounded. A VC++ program that can give different results for the same sum: #include <iostream> #include <float.h> using namespace std;
int main() { float x = 111.599998f; float xvel = .400000006f;
cout.precision(15);
for(int i = 0; i < 2; ++i) { cout << "round control: " << (!i ? "up" : "chop") << endl; unsigned int control_word; _controlfp_s( &control_word, !i ? _RC_UP : _RC_CHOP, _MCW_RC );
double double_sum = x + xvel; float float_sum = x + xvel; int int_sum = x + xvel;
cout << "double: " << double_sum << " float: " << float_sum << " int: " << int_sum << endl; cout << "float sum is " << ( float_sum == 112 ? "equal" : "not equal" ) << " to 112" << endl << endl; } return 0; }
The output depends on what flags it's compiled with, but here's one possibility: round control: up double: 111.999998480082 float: 112 int: 111 float sum is equal to 112
round control: chop double: 111.999998480082 float: 111.999992370605 int: 111 float sum is not equal to 112
|
|
|
|
|
Logged
|
|
|
|
|