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

Login with username, password and session length

 
Advanced search

879357 Posts in 32975 Topics- by 24363 Members - Latest Member: Renegade_Region

May 23, 2013, 09:35:28 PM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Proposing a new Number-Representation: "FixedFloat"
Pages: 1 ... 4 5 [6] 7 8 ... 14
Print
Author Topic: Proposing a new Number-Representation: "FixedFloat"  (Read 4980 times)
J-Snake
Level 10
*****



View Profile WWW Email
« Reply #75 on: March 14, 2013, 06:54:14 PM »

If your concern is perfect consistency, fixed-point wins hands-down.  It's not good at representing "tiny" numbers, but the magnitude (absolute value) of a number isn't important when that number is a coordinate.
For a simulation example it can be when you start generating sensible spring-physics from a resting position then precise translations of tiny space can be important. Resting objects in fixedFloat are always starting motion with the most precise representation. In this case it makes more sense since accelerated objects translate at a lot higher rates compared to the minimal resolution-space of 0.5-1.

But regarding everything overall I see your argument and I certainly have a lot to think about.

Regarding the ease of use, what would you prefer to go with. One nice thing in fixedFloat is that it can work with floats without a conversion loss (in the range of fixedFloat of course), might be usefull here and there, just a nice property at the side, not the ultimate deal-maker.

Also if one is searching an alternative to the coordinate-shifting you can use fixedFloat for that instead. It can take this new role very well. Instead of scaling its full part to submilimeter resolution you can scale it to a range of sufficient resolution you need like 200 meters. The advantage is you don't need to take care of coordinate-shifts and objects further away will be treated with the same precision range since it is periodic. That flexibility of fixedFloat allows you to do that.
« Last Edit: March 14, 2013, 09:44:16 PM by J-Snake » Logged
Evan Balster
Level 10
*****


dreaming close to metal


View Profile WWW Email
« Reply #76 on: March 14, 2013, 10:55:00 PM »

In terms of ease of use, floats are easiest.  For this reason, I use floats.  The other two would be similar to use if implemented as classes, but fixedFloat will require some additional logic on the implementation-side for addition and subtraction that is not necessary for fixed point.  Other operations will be similarly complicated and all will involve a few conversions each.

For a fixedFloat where the fractional part is 0 <= f < 1 the C code for an addition looks like this:

Code:
ff ff_add(ff *a, ff *b)
{
  ff result;
  int carry;
  result.f = a->f + b->f; //0 <= f < 2
  carry = int(result.f); //trucation; equal to (result.f >= 1)
  result.i = a->i + b->i + carry;
  result.f -= carry;
  return result;
}

But, you specifically want to leverage the properties of a float for situations where the number has a magnitude less than one, so you're talking about using -1 < f <= 0 for the float part when the value is negative?  This complicates things.

Code:
ff ff_add(ff *a, ff *b)
{
  ff result;
  int carry;
  result.i = a->i + b->i;
  result.f = a->f + b->f; //-2 < f < 2
  carry = int(result.f); //Trucation; zero unless f's magnitude exceeds one.
  result.f -= carry;

  //We must ensure the sign of the float matches the sign of the int.
  if (result.i > 0 && result.f < .0f) {--result.i; ++result.f;}
  else if (result.i < 0 && result.f > .0f) {++result.i; --result.f;}

  return result;
}

Sticking with this format, let's look at a multiplication:

Code:
ff ff_from_float(float v)
{
  //This actually looks pretty simple thanks to C++'s truncation rules.
  ff result;
  result.i = v;
  result.f = v - result.i;
}

ff ff_mult(ff *a, ff *b)
{
  ff result;
  int aibi = a->i*b->i, carry;
  float aibf = a->i*b->f, afbi = a->f*b->i, afbf = a->f*b->f;

  result.f = aibf+afbi+afbf;
  carry = result.f;
  result.f -= carry;
  result.i = aibi + carry;

  //We must ensure the sign of the float matches the sign of the int.
  if (result.i > 0 && result.f < .0f) {--result.i; ++result.f;}
  else if (result.i < 0 && result.f > .0f) {++result.i; --result.f;}
}

You might be able to cut these down a little, but so can any half-decent optimizing compiler.  Let's compare with a fixed-point multiplication:

Code:
int64 fx_from_float(float v)
{
  return int64(v*float(2<<32));
}

//Multiply two 32.32 numbers
int64 fx_mult(int64 a, int64 b)
{
  //This code isn't 100% portable due to some undefined bitshift/logical-and behavior
  int64 ah = (a >> 32), al = (a&0xFFFFFFFF), bh = (b >> 32), bl = (b&0xFFFFFFFF);
  return ((ah*bh) << 32) + (al*bh + ah*bl) + ((al*bl) >> 32);
}

The fixed-point multiplication code there isn't perfect but gives a generally good measurement of the operation's complexity.  Generally this fx_mult will perform similar or slightly worse than a floating-point multiplication on modern hardware.

When you've got access to an integer type that's twice as long as your fixed-point numbers it gets simpler still:

Code:
//Multiply two 16.16 numbers
int32 fx_mult(int32 a, int32 b)
{
  return int32((int64(a) * int64(b)) >> 16);
}


(By the way, this might be a bit tangental but can anyone tell me what the proper way to extract high and low words during a fixed-point multiply is?  My implementation is subtly wrong or something and it's been giving me aliasing in some of my audio DSPs.)
Logged

Infinite Blank, SoundSelf, Cave Story+, Wreath
voice, accordion, mandolin, (oboe, soon)
Game audio programming consultant.
<plaid/audio>: opensource audio framework
J-Snake
Level 10
*****



View Profile WWW Email
« Reply #77 on: March 15, 2013, 12:17:29 AM »

But, you specifically want to leverage the properties of a float for situations where the number has a magnitude less than one, so you're talking about using -1 < f <= 0 for the float part when the value is negative?  This complicates things.


It doesn't. Addition is commutative. You can leave it that way. Look here:

Code:

 fixedFloat Add(fixedFloat x, fixedFloat y)
        {
            fixedFloat result;
            int trunc = (int)(x.fraction + y.fraction); //magnitude < 2, when not misused

            result.full = x.full + y.full + trunc;
            result.fraction = x.fraction + y.fraction - trunc;

            return result;
        }


You can do Multiplication and rest in fixedFloat for greater precision but that is not necessary to meet the majority of consistency demands. It can be done in float entirely and then assigned to fixedFloat. You can consider fixedFloat just a carrier preparing consistent numbers for more complex operations performed in float so that computation results are reproduceable. This is a healthy philosophy of its treatment.  
« Last Edit: March 15, 2013, 12:42:05 AM by J-Snake » Logged
J-Snake
Level 10
*****



View Profile WWW Email
« Reply #78 on: March 15, 2013, 07:08:17 AM »

http://en.wikipedia.org/wiki/Fixed_float

Don't know who introduced that. Let me know if you have a clue. But it would actually be hard to imagine people working on complex and big games are not using fixedFloat. Its practicability to deal with complex and large space and its compatibility to floats is tempting. They just don't post much.
« Last Edit: March 15, 2013, 07:19:16 AM by J-Snake » Logged
PompiPompi
Level 10
*****



View Profile WWW
« Reply #79 on: March 15, 2013, 07:44:58 AM »

Then use it in your game and tell us how it went.
Logged


Kickstarter? no no no... it's Kicksucker...
Schrompf
Level 1
*

Always one mistake ahead...


View Profile WWW
« Reply #80 on: March 15, 2013, 07:57:06 AM »

But it would actually be hard to imagine people working on complex and big games are not using fixedFloat.

Sorry, but this is getting hilarious. Take a hint from someone who actually has worked in the "professional" game industry: no, they just use floats. Just like PhysX, Bullet, Havoc, like any GPU, like Direct3D or OpenGL... just everybody. Assuming that all the visible proof is just an exception and the invisible is much larger and they all favor your personal approach... this is borderline religious.

Get coding! See for yourself. But seriously: stop talking about it.
Logged

Let's Splatter it and then see if it still moves.
J-Snake
Level 10
*****



View Profile WWW Email
« Reply #81 on: March 15, 2013, 08:16:49 AM »

fixed point in terms of variation:
http://aigamedev.com/open/tutorial/robust-fixed-point-navigation/
Games is a big word. You use what you need to solve the class of problems bothering you.

For example grid-based chess-mechanic is a perfect integer game. You don't want to break it with floats.
Logged
Xienen
Level 2
**


Greater Good Games


View Profile WWW Email
« Reply #82 on: March 15, 2013, 08:20:06 AM »

I'm going to have to back up Schrompf on this.  I know UE3 does not use fixed float internally and I doubt any other big engine/game does because it is inherently slow.  Hardware is built with only 2 real storage types(integers and floats), thus software runs fastest when only using these 2 types.  If anything, only a small and/or low performance requirement game could get away with using something like fixed float.

If hardware added support for fixed float, then it would be possible for big projects to use it, but everyone has gotten pretty used to the limitations of the current float/double system.
Logged

Owner/Programmer at Greater Good Games makers of Break Blocks
Currently developing It Hungers(Unity) and Swipe Attack(UDK)
J-Snake
Level 10
*****



View Profile WWW Email
« Reply #83 on: March 15, 2013, 08:26:04 AM »

fixedFloat is not a concept of a general engine. It is a concept of technical design build on top of it. For example if you decide to go with ugly coordinate-shifts you could consider to use fixedFloat in a way I already explained recently. So it is not unlikely it is actually used, just not talked about.

General advice: you have to think in context in order to understand things properly. It is only that I can distinguish valuable criticism from a incompetent one.
Logged
nikki
Level 10
*****


View Profile Email
« Reply #84 on: March 15, 2013, 08:36:41 AM »

Quote
http://en.wikipedia.org/wiki/Fixed_float

Don't know who introduced that. Let me know if you have a clue.

http://en.wikipedia.org/w/index.php?title=Fixed_float&action=history

tells me :
http://en.wikipedia.org/wiki/User:Rahul.deshmukhpatil

above page has an email adress you can reach Rahul at
Logged
J-Snake
Level 10
*****



View Profile WWW Email
« Reply #85 on: March 15, 2013, 08:45:46 AM »

email already sent, but thanks
Logged
nikki
Level 10
*****


View Profile Email
« Reply #86 on: March 15, 2013, 09:37:59 AM »

I've been reading this thread a few times the last few days and always not getting all the complex terms and everything, But I think I finally get (i hope) what the whole deal is about.
 I'll try to phrase it so you can tell me if I get it and maybe someone as slow as me has some use for my example (if right)


Quote
*  floats are inaccurate.
*  the inaccurancies start 'roughly' after the 8th digit.

The location of the inaccurancies vary between large and small numbers.
I'll show that by using meters for the wrong cases.
I'll put an X at the place where the inaccurancy will start.

smallest distance Earth-Mars 54.6 million km, in meters that is:
54600000.X  meter

smallest bacteria (Mycoplasma) 0.3 micrometer, in meters that is:
0.0000003X meter

The issue is the different size of the inaccurancy (0.1 meter vs 0.00000001 meter)
the proposed fixed float will fix this issue by keeping the number in front of the comma in an integer and that what is behind the comma in a float.

That way you can have an inaccurancy in the scale of bacteria when you are going between Earth and Mars.


did I get it ?

« Last Edit: March 15, 2013, 09:43:00 AM by nikki » Logged
J-Snake
Level 10
*****



View Profile WWW Email
« Reply #87 on: March 15, 2013, 10:36:52 AM »

That way you can have an inaccurancy in the scale of bacteria when you are going between Earth and Mars.
You can see it that way. But what it is about is how it is going to be used to approach those problems. Since it is a concept build entirely by you you have the flexibility to use it in several ways to meet several specs. I currently have a focus on consistency but also relative ease of use, therefore fixed-point can be a too cumbersome deal and is not really necessary to achieve my goal (fixedPoint would also have its problems with some more sensible simulations, in case you want to go for them).

The important thing to understand is that consistency is not entirely determined by the representation of fixedFloat but also on the way you are going to use it. So contraarguments I see all over focusing on the first point are ignoring the other.

For example it doesn't matter that much fixedPoint has the biggest precision advantage in 0.5-1 part of the fraction when things are in considerable motion anyway. What matters more is that I can translate and compute distances of objects at the exact same rates, regardless of their position. Thus fixedFloat acts like a keeper providing consistent numbers. Those numbers can be used as input for floats (I really mean float, not the fraction part) to perform more complex calculations, but all of them are reproduceable since the input is reproduceable. I have already explained my concept of discritized world and snapped objects. You can look it up.

Other than that don't come here to expect the ultimate silver bullet. You won't find one. But I am sharing a concept you might find usefull. So feel free to spend some thought about it. If it doesn't meet your specs then just ignore it and search something else.
« Last Edit: March 15, 2013, 10:42:06 AM by J-Snake » Logged
Evan Balster
Level 10
*****


dreaming close to metal


View Profile WWW Email
« Reply #88 on: March 15, 2013, 12:07:02 PM »

J-Snake:

Code:
fixedFloat Add(fixedFloat x, fixedFloat y)
        {
            fixedFloat result;
            int trunc = (int)(x.fraction + y.fraction); //magnitude < 2, when not misused

            result.full = x.full + y.full + trunc;
            result.fraction = x.fraction + y.fraction - trunc;

            return result;
        }

This code has a flaw which I will demonstrate:

a = -1.95 = {-1, -.95}
b = +2.06 = {+2, +.06}
trunc = int(-.95 + .06) = int(-.89) = 0
r = {-1 + 2 + 0, -.95 + .06 - 0} = {+1, -.89}

if {+1, -.89} is a valid value, then there are two possible representations for every number in FixedFloat and that is obviously problematic...

Having worked with fixed-point numbers, I doubt they'll be any more cumbersome than this representation unfortunately.  Both are a bit of a pain, but with fixed point there are some very nice libraries that have done the work for you.

Please post your "spec".


Nikki:

The extent of a float is in significant digits, so you can express a float like so:
M.MMMMMM * 10E

In the case of a large number like the distance to the moon in inches, E is positive.  With a small number like the size of that bacterium, E is negative.  Thus the inaccuracy in that small number is more like this:
0.0000003000000X (3.000000 * 10-7)

EDIT:  Perhaps I misunderstood your question.  When you're on Mars, you won't be able to represent the position of a bacterium accurately, because the "steps" between numbers are larger than the object itself, and that is indeed a problem.  The easiest way to solve this in my opinion is to use the same "step size" everywhere -- this technique is known as fixed-point.


This thing: http://en.wikipedia.org/wiki/Fixed_float

The format described here is extremely naive and should not be taken seriously.  It's dramatically less practical than the format we've been assessing in this thread.
« Last Edit: March 15, 2013, 12:15:53 PM by Evan Balster » Logged

Infinite Blank, SoundSelf, Cave Story+, Wreath
voice, accordion, mandolin, (oboe, soon)
Game audio programming consultant.
<plaid/audio>: opensource audio framework
J-Snake
Level 10
*****



View Profile WWW Email
« Reply #89 on: March 15, 2013, 12:34:43 PM »

if {+1, -.89} is a valid value, then there are two possible representations for every number in FixedFloat and that is obviously problematic...
It is a valid representation. The error rate is in small consistent borders exactly known and which you cannot exceed and is indipendent of the macroscopic location. The integer part is for the perfect representation of the discritized world. The main point of the fraction is precision, which in general is always better if you can get more of it "for free". Keep in mind that in general you cannot get the exact same result of the same experiment when things are in motion anyway since the initial fraction parts can differ. But you can guarantee a maximum border for the error. But once an experiment is rolling from its snapped position things will add uniformly (no aliasing here). In that case you can expect the exact same results, indipendent from its initial discritized position.

Why is that spec so fundamental here? Take a look at 0:30, the action where I perfectly fly through the hole.

http://www.youtube.com/watch?v=v9L0ikvd0XI&list=UUzrgKA2NpfnvMeUzLVnN3vA&index=5

The input-sequence can be perfectly replicated (frame by frame). With a system respecting this spec I can shift my world to any location I want. I can every time replicate the exact same action. That is actually what the player wants. When he finds a geometric constellation of things he has mastered he expects to replicate it every time, no matter where the same geometric constellation of things is located (be it a shifted platform, a replicated area etc.).
« Last Edit: March 15, 2013, 01:39:23 PM by J-Snake » Logged
Pages: 1 ... 4 5 [6] 7 8 ... 14
Print
Jump to:  

Theme orange-lt created by panic