Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

891213 Posts in 33530 Topics- by 24770 Members - Latest Member: Alexis Moroz

June 19, 2013, 07:50:20 AM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Riddle me this, Batman
Pages: [1] 2 3
Print
Author Topic: Riddle me this, Batman  (Read 1646 times)
Ben_Hurr
Level 10
*****


nom nom nom


View Profile Email
« 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
Level 5
*****


Totally.


View Profile
« 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
Level 10
*****


glitch


View Profile WWW Email
« 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

My projects:<br />Games: Jumpman Retro-futuristic platforming iJumpman iPhone version Drumcircle PC+smartphone music toy<br />More: RUN HELLO
Ben_Hurr
Level 10
*****


nom nom nom


View Profile Email
« 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
Level 2
**



View Profile Email
« 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.

 Big Laff
Logged
Ben_Hurr
Level 10
*****


nom nom nom


View Profile Email
« Reply #6 on: March 09, 2012, 12:51:08 PM »

Yay, time to switch to Integers for fractional numbers.  Facepalm

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.  Angry
« Last Edit: March 09, 2012, 01:08:36 PM by Ben_Hurr » Logged
powly
Level 3
***



View Profile WWW
« Reply #7 on: March 09, 2012, 01:25:00 PM »

...

Logged
Ben_Hurr
Level 10
*****


nom nom nom


View Profile Email
« Reply #8 on: March 09, 2012, 01:49:00 PM »



And then you convert all the Floats to Doubles, and get 111.9~  Crazy
I'm starting to hate floating point numbers.
Logged
powly
Level 3
***



View Profile WWW
« 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
Level 10
*****


nom nom nom


View Profile Email
« 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
Level 3
***



View Profile WWW
« 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
Level 10
*****


nom nom nom


View Profile Email
« Reply #12 on: March 09, 2012, 02:34:38 PM »

I fixed by using an intermediary variable.  It still feels gross and hacky though.  Cry
Logged
Belimoth
Level 9
****


Pharoah Bourbon


View Profile
« 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.

Code:
sum:Float = x + xvel
Print sum
sum = sum - xvel
Print sum
Logged

ham and brie
Level 2
**



View Profile Email
« 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:
Code:
#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:
Code:
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
Pages: [1] 2 3
Print
Jump to:  

Theme orange-lt created by panic