Weird impy thing
Register | 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 00:43. Post New Thread    Post A Reply
Quasar
Moderator


Posts: 5757
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 08-29-12 at 03:10

Old Post 08-29-12 03:04 #
Quasar is offline Profile || Blog || PM || Email || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
DaniJ
Forum Staple


Posts: 2055
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 08-29-12 at 05:48

Old Post 08-29-12 05:31 #
DaniJ is offline Profile || Blog || PM || Search || Add Buddy IP || Edit/Delete || Quote
Graf Zahl
Why don't I have a custom title by now?!


Posts: 7626
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 08-29-12 07:21 #
Graf Zahl is offline Profile || Blog || PM || Email || Search || Add Buddy IP || Edit/Delete || Quote
printz
CRAZY DUMB ZEALOT


Posts: 8541
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

Old Post 08-29-12 08:24 #
printz is offline Profile || Blog || PM || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
marineController
Mini-Member


Posts: 56
Registered: 08-12


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

Old Post 08-29-12 15:36 #
marineController is offline Profile || Blog || PM || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
printz
CRAZY DUMB ZEALOT


Posts: 8541
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

Old Post 08-29-12 15:45 #
printz is offline Profile || Blog || PM || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
Graf Zahl
Why don't I have a custom title by now?!


Posts: 7626
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 08-29-12 18:00 #
Graf Zahl is offline Profile || Blog || PM || Email || Search || Add Buddy IP || Edit/Delete || Quote
ducon
Régulier du Forum


Posts: 1288
Registered: 12-03


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

__________________
A shell, an imp.

Old Post 08-29-12 18:17 #
ducon is offline Profile || Blog || PM || Email || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
printz
CRAZY DUMB ZEALOT


Posts: 8541
Registered: 06-06


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

__________________
Automatic Wolfenstein - Version 1.0

Old Post 08-29-12 18:33 #
printz is offline Profile || Blog || PM || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
Quasar
Moderator


Posts: 5757
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 08-29-12 at 18:46

Old Post 08-29-12 18:39 #
Quasar is offline Profile || Blog || PM || Email || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
printz
CRAZY DUMB ZEALOT


Posts: 8541
Registered: 06-06


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

__________________
Automatic Wolfenstein - Version 1.0

Old Post 08-29-12 18:41 #
printz is offline Profile || Blog || PM || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
Quasar
Moderator


Posts: 5757
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 08-29-12 18:47 #
Quasar is offline Profile || Blog || PM || Email || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
DaniJ
Forum Staple


Posts: 2055
Registered: 08-03


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

Old Post 08-29-12 18:50 #
DaniJ is offline Profile || Blog || PM || Search || Add Buddy IP || Edit/Delete || 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 08-29-12 19:30 #
exp(x) is offline Profile || Blog || PM || Email || Search || Add Buddy IP || Edit/Delete || Quote
Quasar
Moderator


Posts: 5757
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 08-30-12 02:55 #
Quasar is offline Profile || Blog || PM || Email || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
DaniJ
Forum Staple


Posts: 2055
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 08-30-12 03:15 #
DaniJ is offline Profile || Blog || PM || Search || Add Buddy IP || Edit/Delete || Quote
GhostlyDeath
Forum Retard


Posts: 1027
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 08-30-12 04:00 #
GhostlyDeath is offline Profile || Blog || PM || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
Blzut3
Member


Posts: 464
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 08-30-12 11:58 #
Blzut3 is offline Profile || Blog || PM || Email || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
wesleyjohnson
Forum Regular


Posts: 935
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 08-31-12 at 05:00

Old Post 08-31-12 04:50 #
wesleyjohnson is offline Profile || Blog || PM || Search || Add Buddy IP || Edit/Delete || Quote
Ladna
Member


Posts: 271
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 08-31-12 10:29 #
Ladna is offline Profile || Blog || PM || Email || Search || Add Buddy IP || Edit/Delete || Quote
printz
CRAZY DUMB ZEALOT


Posts: 8541
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

Old Post 08-31-12 11:56 #
printz is offline Profile || Blog || PM || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
Siggi
Member


Posts: 388
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 08-31-12 at 14:17

Old Post 08-31-12 13:36 #
Siggi is offline Profile || Blog || PM || Email || Search || Add Buddy IP || Edit/Delete || Quote
Quasar
Moderator


Posts: 5757
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 08-31-12 15:08 #
Quasar is offline Profile || Blog || PM || Email || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
Blzut3
Member


Posts: 464
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 08-31-12 18:10 #
Blzut3 is offline Profile || Blog || PM || Email || Homepage || Search || Add Buddy IP || Edit/Delete || Quote
Moriarti
Warming Up


Posts: 26
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 08-31-12 23:51 #
Moriarti is offline Profile || Blog || PM || Search || Add Buddy IP || Edit/Delete || Quote
andrewj
Senior Member


Posts: 1606
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 09-01-12 at 04:59

Old Post 09-01-12 04:40 #
andrewj is offline Profile || Blog || PM || Search || Add Buddy IP || Edit/Delete || Quote
All times are GMT. The time now is 00:43. 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.

Message Board Statistics