Cyberdemon
User Profile | Member List | F.A.Q | Privacy Policy | New Blog | Search Forums | Forums Home
Doomworld Forums : Powered by vBulletin version 2.2.5 Doomworld Forums > Classic Doom > Source Ports > I know floats are inexact but damn...
 
Author
All times are GMT. The time now is 16:09. Post New Thread    Post A Reply
Quasar
Moderator


Posts: 6497
Registered: 08-00


If EE is compiled using GCC 4.2.1.20070719 on platform i386-unknown-openbsd, the following check fails:
code:
if(vbscreen.getVirtualAspectRatio() <= 4.0/3.0) return;
With the exception of modes 320x200 and 640x400, which are treated specially, the function in question basically does this:
code:
return static_cast<double>(width) / height;
Regardless of the input screen dimensions, if the aspect ratio is 4/3, such as in modes 640x480 or 1024x768, the comparison always fails, leading to a frequent crash and other side effects.

I have to believe this isn't just floating point inaccuracy, because the value in question 4/3 is, in ideal real math, 1.3333... - this should not be getting rounded UP at all, rather if anything I'd expect the binary float truncation to have a value less than real 4/3. Either the folded constant value in the EXE is less than 4/3 and the function is accurate, or the constant is correct and the function returns a value > 4/3.

Anybody else ever ran into this?

Last edited by Quasar on Aug 29 2012 at 03:10

Old Post Aug 29 2012 03:04 #
Quasar is offline Twitter account Youtube Github || Blog || PM || Post History || Add Buddy IP || Edit || Quote
DaniJ
Senior Member


Posts: 2298
Registered: 08-03


Can you post the body of getVirtualAspectRatio() ? If you are truly returning double(width=640) / height=480 then I would certainly be worried. Though, round up can happen, particularly when a double for such a number as 1.333... is truncated to a float. So I would add an epsilon, or change your representation (seems too error prone and may lead to subtle (or not) bugs).

Last edited by DaniJ on Aug 29 2012 at 05:48

Old Post Aug 29 2012 05:31 #
DaniJ is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Graf Zahl
Why don't I have a custom title by now?!


Posts: 8059
Registered: 01-03


Hint: Never EVER compare floats for equality. Since by their very nature some values will get rounded you'll always get into situations where such a comparison will fail.


4/3 can neither be represented exactly as a decimal nor a binary value.

Old Post Aug 29 2012 07:21 #
Graf Zahl is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
printz
CRAZY DUMB ZEALOT


Posts: 9202
Registered: 06-06


Is there a common practice for float comparison margin of error, or is it a case-by-case situation?

__________________
Automatic Wolfenstein - Version 1.0.1 - also on Android (Updated 28/03/2015)

Old Post Aug 29 2012 08:24 #
printz is offline Twitter account Youtube Github || Blog || PM || Post History || Add Buddy IP || Edit || Quote
marineController
Mini-Member


Posts: 59
Registered: 08-12


Maybe Dooms fixed point can help you: http://pastebin.com/0NnHAxDp

Old Post Aug 29 2012 15:36 #
marineController is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
printz
CRAZY DUMB ZEALOT


Posts: 9202
Registered: 06-06


Would adding 1e-x (where x is an exponent) to 4.0/3.0 fix the problem? Which is the best x for double comparison margin of error?

__________________
Automatic Wolfenstein - Version 1.0.1 - also on Android (Updated 28/03/2015)

Old Post Aug 29 2012 15:45 #
printz is offline Twitter account Youtube Github || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Graf Zahl
Why don't I have a custom title by now?!


Posts: 8059
Registered: 01-03



marineController said:
Maybe Dooms fixed point can help you: http://pastebin.com/0NnHAxDp


No, not at all. Imprecisions come from numbers not being representable as binary values. Fixing the number of digits doesn't change anything about this problem. Besides, there is no case where 32 bit fixed point can be more precise than a 64 bit double.

Old Post Aug 29 2012 18:00 #
Graf Zahl is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
ducon
Régulier du Forum


Posts: 1436
Registered: 12-03


If you want to test such things, try multiplications instead, they will be exact.

__________________
A shell, an imp.

Old Post Aug 29 2012 18:17 #
ducon is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
printz
CRAZY DUMB ZEALOT


Posts: 9202
Registered: 06-06


"width/height <= 4/3" is "width*3 <= 4*height". Nice :)

__________________
Automatic Wolfenstein - Version 1.0.1 - also on Android (Updated 28/03/2015)

Old Post Aug 29 2012 18:33 #
printz is offline Twitter account Youtube Github || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Quasar
Moderator


Posts: 6497
Registered: 08-00



Graf Zahl said:
No, not at all. Imprecisions come from numbers not being representable as binary values. Fixing the number of digits doesn't change anything about this problem. Besides, there is no case where 32 bit fixed point can be more precise than a 64 bit double.

Yes it does, because integer division doesn't round, it chops.

4 * FRACUNIT / 3 will *always* be equal to any other integer division of numbers with the same ratio. 640 * FRACUNIT / 480 will give the same result. Try it yourself if you don't buy the chart he posted. Either way, I've already replaced the floating point aspect ratio methods with fixed-point ones, resulting in this problem being repaired.

Integer math also isn't subject to the "false precision" problem, which seems to be the cause of this particular failure. 4/3 stored in the executable has the form of a 64-bit serialized IEEE-754 double precision number, but 4/3 calculated at runtime on an Intel has 80 bits of precision. The calculated value always compares as greater than the constant simply because it has more bits set (somewhat meaninglessly) to 1.

Last edited by Quasar on Aug 29 2012 at 18:46

Old Post Aug 29 2012 18:39 #
Quasar is offline Twitter account Youtube Github || Blog || PM || Post History || Add Buddy IP || Edit || Quote
printz
CRAZY DUMB ZEALOT


Posts: 9202
Registered: 06-06


So if you have 801x600, it will register as widescreen? :-/

__________________
Automatic Wolfenstein - Version 1.0.1 - also on Android (Updated 28/03/2015)

Old Post Aug 29 2012 18:41 #
printz is offline Twitter account Youtube Github || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Quasar
Moderator


Posts: 6497
Registered: 08-00



printz said:
So if you have 801x600, it will register as widescreen? :-/

I already told you we don't support use of weird modes like that, just because it's technically possible. So yes, it will.

Old Post Aug 29 2012 18:47 #
Quasar is offline Twitter account Youtube Github || Blog || PM || Post History || Add Buddy IP || Edit || Quote
DaniJ
Senior Member


Posts: 2298
Registered: 08-03


I'd be interested to hear why (not that I'm doubting you have a valid reason).

Old Post Aug 29 2012 18:50 #
DaniJ is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
exp(x)


Posts: 2595
Registered: 04-04



ducon said:
If you want to test such things, try multiplications instead, they will be exact.

This.

Instead of testing a/b <= c/d as floats, test a*d <= c*b as ints. Note that if for some reason one of the denominators is negative, you need to flip the inequality.

Old Post Aug 29 2012 19:30 #
exp(x) is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Quasar
Moderator


Posts: 6497
Registered: 08-00



DaniJ said:
I'd be interested to hear why (not that I'm doubting you have a valid reason).

Well, where in the region of deformed screen shapes between 4:3 and 16:10 do I declare the boundary to have been crossed into "widescreen" territory? I could always set the boundary at 16:10 or wider, I suppose, but then somebody will complain no doubt about their 16:11 custom windowed resolution not being treated as widescreen.

It's kind of arbitrary.

Old Post Aug 30 2012 02:55 #
Quasar is offline Twitter account Youtube Github || Blog || PM || Post History || Add Buddy IP || Edit || Quote
DaniJ
Senior Member


Posts: 2298
Registered: 08-03


I'm not sure I understand the desire to classify an aspect ratio as "widescreen" or not. As you say, its rather arbitrary. In Doomsday we don't classify, all we care about is whether the aspect ratio is 4:3 and/or whether to stretch the render or not.

Old Post Aug 30 2012 03:15 #
DaniJ is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
GhostlyDeath
Forum Retard


Posts: 1041
Registered: 08-05


The pixel buffer resolution tells you the aspect ratio? I thought it was the actual physical size of the viewing surface.

It would be best to have an option that says you want either 4:3 or whatever else. I know my Wii does this, even though the analog component cables are naturally 4:3, you can view it like it was 16:9.

Old Post Aug 30 2012 04:00 #
GhostlyDeath is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Blzut3
Member


Posts: 575
Registered: 06-04



GhostlyDeath said:
It would be best to have an option that says you want either 4:3 or whatever else. I know my Wii does this, even though the analog component cables are naturally 4:3, you can view it like it was 16:9.

While I do recommend that any source port supporting widescreen/tallscreen to have anamorphic options. It is still recommended to detect automatically based on the virtual aspect ratio. This is slightly harder than just comparing the ratio between the width and height since some widescreen monitors are not exactly 16:9, 16:10, (or recently somewhere around 17:10). Having to manually select is the only option on TVs since the virtual aspect ratio isn't the same as the physical (IIRC it's not even 4:3).

Here's an ACS approximation of the function ZDoom uses to determine the ratio if it's of any use. (Although it looks like that page still needs to be updated for 17:10.)

Old Post Aug 30 2012 11:58 #
Blzut3 is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
wesleyjohnson
Senior Member


Posts: 1133
Registered: 04-09


Just guessing, but the 4.0/3.0 could have been rounded by the compiler because it was not told to use (double).
Rounding is likely because the floating point unit has more register bits than are stored in memory.
The compiler must store the 4/3 constant, so it would round the low bits to 000.
The function result would still be in the floating point registers with all its digits.
The double function result would continue with more digits, so the double function result is larger.

Edit: This is the same thing that Quasar was saying, but I did not read it that way the first time.

if( fabs( vbscreen.getVirtualAspectRatio() - (4.0/3.0)) < 0.01 )
return;

Last edited by wesleyjohnson on Aug 31 2012 at 05:00

Old Post Aug 31 2012 04:50 #
wesleyjohnson is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Ladna
Member


Posts: 354
Registered: 04-10



Quasar said:
4/3 stored in the executable has the form of a 64-bit serialized IEEE-754 double precision number, but 4/3 calculated at runtime on an Intel has 80 bits of precision. The calculated value always compares as greater than the constant simply because it has more bits set (somewhat meaninglessly) to 1.

That is fucking madness. I thought IEEE-754 was supposed to fix all that, but I guess not.

Some other people have asked if there's like an equivalence tolerance, like if it's within .00001 difference then the numbers are equal. There is, it's called an epsilon value, and it's a big pain in the ass. You may as well just typedef a struct with the whole & fraction parts separate.... oh hey fixed point....

Old Post Aug 31 2012 10:29 #
Ladna is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
printz
CRAZY DUMB ZEALOT


Posts: 9202
Registered: 06-06



Ladna said:
There is, it's called an epsilon value, and it's a big pain in the ass.

Well, in lack of time or in lack of need, I can just go with a gross value.

__________________
Automatic Wolfenstein - Version 1.0.1 - also on Android (Updated 28/03/2015)

Old Post Aug 31 2012 11:56 #
printz is offline Twitter account Youtube Github || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Siggi
Member


Posts: 390
Registered: 10-04



Blzut3 said:
Here's an ACS approximation of the function ZDoom uses to determine the ratio if it's of any use. (Although it looks like that page still needs to be updated for 17:10.)

Does ZDoom only ever display at 4:3, 5:4, 16:9, 16:10 or perhaps 17:10 in spite of whatever resolution you've set? Surely this doesn't work for the hypothetical bizarre windowed modes.

edit: perhaps to answer my own question, it seems ZDoom doesn't allow bizarre resolutions at all, even in Windowed modes.

Last edited by Siggi on Aug 31 2012 at 14:17

Old Post Aug 31 2012 13:36 #
Siggi is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Quasar
Moderator


Posts: 6497
Registered: 08-00


It might clear up some issues in this thread if I explain that the code in question is to determine whether or not screen patches will be drawn onto a centered 4:3 subscreen of a widescreen video buffer.

It has *nothing* to do with the first-person renderer.

Old Post Aug 31 2012 15:08 #
Quasar is offline Twitter account Youtube Github || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Blzut3
Member


Posts: 575
Registered: 06-04



Siggi said:
Does ZDoom only ever display at 4:3, 5:4, 16:9, 16:10 or perhaps 17:10 in spite of whatever resolution you've set? Surely this doesn't work for the hypothetical bizarre windowed modes.

Yes, ZDoom will only display within a predefined set of aspect ratios. This does work out somewhat better that allowing bizarre ratios since mod authors can design UI elements for the supported ratio. (Even adding 17:10 for netbooks resulting in a large number of groans.)

Technically there's nothing stopping ZDoom from rendering at an odd resolution, but it will be corrected as if it was 4:3. Unless it's close enough to one of the supported wide/tallscreen ratios. (Note that there are a lot of wide screen resolutions that are not exactly 16:9 or 16:10, but only off by a few pixels. Likewise 1024x600 isn't exactly 17:10, but it's a close enough approximation.)

Old Post Aug 31 2012 18:10 #
Blzut3 is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
Moriarti
Green Marine


Posts: 30
Registered: 02-04



Quasar said:
4/3 stored in the executable has the form of a 64-bit serialized IEEE-754 double precision number, but 4/3 calculated at runtime on an Intel has 80 bits of precision. The calculated value always compares as greater than the constant simply because it has more bits set (somewhat meaninglessly) to 1.

To avoid this problem, you can use _FPU_GETCW/FPU_SETCW on GCC to set the number of bits of precision to run the FPU registers at. Visual C++ has _control87, but its runtime already sets the FPU to use double-sized registers, so you don't need to use it for that compiler.

Old Post Aug 31 2012 23:51 #
Moriarti is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
andrewj
Senior Member


Posts: 1705
Registered: 04-02



Moriarti said:
To avoid this problem, you can use _FPU_GETCW/FPU_SETCW on GCC to set the number of bits of precision to run the FPU registers at.

You need to #include <fpu_control.h> for these, and only apply to the x86 architecture.

However it is still best to use epsilons when comparing floating point values.

Last edited by andrewj on Sep 1 2012 at 04:59

Old Post Sep 1 2012 04:40 #
andrewj is offline || Blog || PM || Post History || Add Buddy IP || Edit || Quote
All times are GMT. The time now is 16:09. Post New Thread    Post A Reply
 
Doomworld Forums : Powered by vBulletin version 2.2.5 Doomworld Forums > Classic Doom > Source Ports > I know floats are inexact but damn...

Show Printable Version | Email this Page | Subscribe to this Thread

 

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are OFF
[IMG] code is ON
 

< Contact Us - Doomworld >

Powered by: vBulletin Version 2.2.5
Copyright ©2000, 2001, Jelsoft Enterprises Limited.