• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Muzzy A

Cos is not returning 0 for 90 degrees or PI/2

33 posts in this topic

[code]
Vector2 Rotate( Vector2 &vec,float Angle )
{
/*
cos -sin
sin cos
*/

// When the Angle is PI/2 (90 degrees), it doesn't return 0, we get 4.37114e-008
float Cos = cos(Angle);
float Sin = sin(Angle);

Vector2 rot = Vector2( Cos*vec.x - Sin*vec.y , Sin*vec.x + Cos*vec.y );

return rot;
}

// If i pass this vector
Vector2 vec = Vector2(0,1);
vec = Rotate(vec,PI*.5f);

// The answer should be '(1,0)'
// But i ACTUALLY get '(-1,-4.37114e-008)'....

/* Anyone know what's going on here, is sin and cos incapable of returning 0? */

[/code] Edited by Muzzy A
0

Share this post


Link to post
Share on other sites
I get the same behaviour, where the answer is -4.37114e-008 for float and 6.12323e-017 for double. Consider that [eqn]\pi[/eqn] is irrational, and so you shouldn't really expect a perfect answer. When you use a digital computer / calculator and plug in [eqn]\cos(\pi / 2)[/eqn] and get an answer of precisely zero, it's likely because the person who coded the calculator put in a special conditional statement that says something similar to "if(answer < epsilon && answer > -epsilon) { answer = 0; }", where epsilon is some tiny number like 1e-7.

Don't lose sleep over it. Edited by taby
0

Share this post


Link to post
Share on other sites
[quote name='Muzzy A' timestamp='1337404899' post='4941354']
// The answer should be '(1,0)'
// But i ACTUALLY get '(-1,-4.37114e-008)'....

[/quote]

Well, the answer should be (-1,0), which it basically is... You can't expect infinite precision in floating-point operations.

EDIT: If instead of an angle you were to use a unit vector containing the angle's cosine and sine, you could just do this and not have the problem:
[code]Vector2D rotate(Vector2D vec, Vector2D rot) {
return Vector2D(vec.x*rot.x - vec.y*rot.y, vec.x*rot.y + vec.y*rot.x); // Notice this is just multiplication of complex numbers!
}

Vector2 vec = Vector2(0,1);
vec = Rotate(vec,Vector2D(0,1));
[/code] Edited by alvaro
2

Share this post


Link to post
Share on other sites
Not that it has anything to do with your question, but `vec' should not be a non-const reference: Either make it const or remove the `&'.
0

Share this post


Link to post
Share on other sites
[url="http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html"]What Every Computer Scientist Should Know About Floating-Point Arithmetic[/url]

-4.37114e-008 = -.0000000437114 (which is pretty dang close to zero)
2

Share this post


Link to post
Share on other sites
[quote name='Cornstalks' timestamp='1337411593' post='4941373']
[url="http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html"]What Every Computer Scientist Should Know About Floating-Point Arithmetic[/url]

-4.37114e-008 = -.0000000437114 (which is pretty dang close to zero)
[/quote]

oh, i assumed it was a garbage number that it spit out cause it didn't know what to do lol

thanks guys


[quote name='alvaro' timestamp='1337410309' post='4941369']
[quote name='Muzzy A' timestamp='1337404899' post='4941354']
// The answer should be '(1,0)'
// But i ACTUALLY get '(-1,-4.37114e-008)'....

[/quote]

Well, the answer should be (-1,0)

[/quote]

lol oops Edited by Muzzy A
1

Share this post


Link to post
Share on other sites
[quote name='taby' timestamp='1337410191' post='4941368']
it's likely because the person who coded the calculator put in a special conditional statement that says something similar to "if(answer < epsilon && answer > -epsilon) { answer = 0; }", where epsilon is some tiny number like 1e-7.
[/quote]
It turns out the language has a constant for the actual epsilon that should be used for that. Proper use of FLT_EPSILON would apply here.

( In this case, the answer is ten times smaller than FLT_EPSILON, so ten times smaller than rounding error. )
0

Share this post


Link to post
Share on other sites
Calculators generally work to a much higher precision than what they display. For example the Windows calculator (at least on recent versions of windows) has about 40 significant digits of precision (calculate sqrt(4) - 2 to see that). They then round the answer to fit the number of digits on the display.

Note that FLT_EPSILON is simply the minimum positive float such that 1.0f + FLT_EPSILON != 1.0f so the epsilon value you want to use depends on the magnitude of the expected answer. In the case of sin and cos it's probably the right epsilon to use, but in other cases it won't be.
2

Share this post


Link to post
Share on other sites
[quote name='Cornstalks' timestamp='1337411593' post='4941373']
-4.37114e-008 = -.0000000437114 (which is pretty dang close to zero)
[/quote]

Not if you're calculating the mass defect of an atom nucleus decaying by beta-radiation [img]http://public.gamedev.net//public/style_emoticons/default/cool.png[/img]
which I currently have to do for class... 4,014e-31 kg...
0

Share this post


Link to post
Share on other sites
[quote name='Zoomulator' timestamp='1337590478' post='4941864']
Not if you're calculating the mass defect of an atom nucleus decaying by beta-radiation [img]http://public.gamedev.net//public/style_emoticons/default/cool.png[/img]
[/quote]
In which case choosing stock float as the data type to use is quite obviously a baaaaaaaaaaaaaaaaaad idea.
0

Share this post


Link to post
Share on other sites
[quote name='mhagain' timestamp='1337591469' post='4941868']
[quote name='Zoomulator' timestamp='1337590478' post='4941864']
Not if you're calculating the mass defect of an atom nucleus decaying by beta-radiation [img]http://public.gamedev.net//public/style_emoticons/default/cool.png[/img]
[/quote]
In which case choosing stock float as the data type to use is quite obviously a baaaaaaaaaaaaaaaaaad idea.
[/quote]
True enough.. though a double float would work fine.
0

Share this post


Link to post
Share on other sites
[quote name='Cornstalks' timestamp='1337608410' post='4941910']
I'm not saying a [font=courier new,courier,monospace]double[/font] wouldn't work or that it wouldn't be the better choice in your case. I'm saying it isn't the [b][i]number[/i][/b] that's usually limiting you, it's usually the [b][i]number[u]s[/u][/i][/b] and what you're [b][i]doing[/i][/b] with the numbers. It's a subtle but significant difference of focus.
[/quote]
Yup, which is why the other discussion is pointless. The OP said what he was doing.

The OP is computing a cosine.

For the operation the scale is (0,1).

Considering the range of the result, the margin of error is based on 1.0*FLT_EPSILON, which in turn puts his stated result as within the error tolerance of 0.
1

Share this post


Link to post
Share on other sites
[quote name='frob' timestamp='1337490764' post='4941587']
[quote name='taby' timestamp='1337410191' post='4941368']
it's likely because the person who coded the calculator put in a special conditional statement that says something similar to "if(answer < epsilon && answer > -epsilon) { answer = 0; }", where epsilon is some tiny number like 1e-7.
[/quote]
It turns out the language has a constant for the actual epsilon that should be used for that. Proper use of FLT_EPSILON would apply here.

( In this case, the answer is ten times smaller than FLT_EPSILON, so ten times smaller than rounding error. )
[/quote]

There's always numeric_limit's epsilon(), and that would technically be the proper use of the language, but whatever you say.
0

Share this post


Link to post
Share on other sites
[quote name='Adam_42' timestamp='1337514957' post='4941624']
Calculators generally work to a much higher precision than what they display. For example the Windows calculator (at least on recent versions of windows) has about 40 significant digits of precision (calculate sqrt(4) - 2 to see that). They then round the answer to fit the number of digits on the display.

Note that FLT_EPSILON is simply the minimum positive float such that 1.0f + FLT_EPSILON != 1.0f so the epsilon value you want to use depends on the magnitude of the expected answer. In the case of sin and cos it's probably the right epsilon to use, but in other cases it won't be.
[/quote]

Thanks for that. :) Edited by taby
0

Share this post


Link to post
Share on other sites
[quote name='Cornstalks' timestamp='1337411593' post='4941373']
[url="http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html"]What Every Computer Scientist Should Know About Floating-Point Arithmetic[/url]

-4.37114e-008 = -.0000000437114 (which is pretty dang close to zero)
[/quote]

Add this to that list (which makes the ramifications of difference in order of magnitude a bit more transparent):
[url="http://www.drdobbs.com/cpp/184403224"]http://www.drdobbs.com/cpp/184403224[/url] Edited by taby
0

Share this post


Link to post
Share on other sites
[quote name='frob' timestamp='1337617427' post='4941946']
[quote name='Cornstalks' timestamp='1337608410' post='4941910']
I'm not saying a [font=courier new,courier,monospace]double[/font] wouldn't work or that it wouldn't be the better choice in your case. I'm saying it isn't the [b][i]number[/i][/b] that's usually limiting you, it's usually the [b][i]number[u]s[/u][/i][/b] and what you're [b][i]doing[/i][/b] with the numbers. It's a subtle but significant difference of focus.
[/quote]
Yup, which is why the other discussion is pointless. The OP said what he was doing.

The OP is computing a cosine.

For the operation the scale is (0,1).

Considering the range of the result, the margin of error is based on 1.0*FLT_EPSILON, which in turn puts his stated result as within the error tolerance of 0.
[/quote]

Not to be nit-picky or anything, but it's not computing the cosine that introduces an error here: The error in this situation comes from not being able to represent pi/2 precisely as a float. We are computing the cosine of pi/2+epsilon, which should be very close to -epsilon.

The smallest value of epsilon for which pi/2+epsilon is representable is .00000004371139000186... , so the number the OP was getting is very well explained by my story, and the error introduced by the computation of the cosine is a second-order effect. Edited by alvaro
1

Share this post


Link to post
Share on other sites
[quote name='alvaro' timestamp='1337623057' post='4941970']
Not to be nit-picky or anything, but it's not computing the cosine that introduces an error here: The error in this situation comes from not being able to represent pi/2 precisely as a float. We are computing the cosine of pi/2+epsilon, which should be very close to -epsilon.

The smallest value of epsilon for which pi/2+epsilon is representable is .00000004371139000186... , so the number the OP was getting is very well explained by my story, and the error introduced by the computation of the cosine is a second-order effect.
[/quote]

I don't think that you're being too nitpicky, because while I do think that both sides of the coin are applicable here, the error does technically spring up from the less-than-perfect definition of pi. I should have thrown in a mention of float pi_half = acos(0.0f); cout << cos(pi_half) << endl; and of epsilon() alongside the mention of irrational numbers to explain what I meant a little better, because it's how I indirectly double-checked the OP's definition of pi. [img]http://public.gamedev.net//public/style_emoticons/default/mellow.png[/img]

I also mentioned digital computers to contrast against [url="http://www.wisegeek.com/what-is-an-analog-computer.htm"]analog[/url] [url="http://sf0.org/levitatingpotato/Analog-Computer-Creation/"]computers[/url], but again, I didn't explain very well what I meant. Edited by taby
0

Share this post


Link to post
Share on other sites
Some very good information is explained on this [url="http://randomascii.wordpress.com/"]blog[/url]. Actually most (if not all) of his recent blog posts refer to floating point calculations and the mystery behind them.

Scroll down to the 'Catastrophic cancellation, hiding in plain sight' section.
http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

Alvaro basically hit it spot on. i.e. You're not calculating the sin of PI... you're calculating the sin of (float)pi, or (double)pi. PI, as a whole, can't be represented as a float or even a double. So there is error in the calculations.
0

Share this post


Link to post
Share on other sites
[quote name='web383' timestamp='1337634063' post='4942004']
Some very good information is explained on this [url="http://randomascii.wordpress.com/"]blog[/url]. Actually most (if not all) of his recent blog posts refer to floating point calculations and the mystery behind them.

Scroll down to the 'Catastrophic cancellation, hiding in plain sight' section.
[url="http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/"]http://randomascii.w...s-2012-edition/[/url]

Alvaro basically hit it spot on. i.e. You're not calculating the sin of PI... you're calculating the sin of (float)pi, or (double)pi. PI, as a whole, can't be represented as a float or even a double. So there is error in the calculations.
[/quote]

Yeah... because it's irrational... [img]http://public.gamedev.net//public/style_emoticons/default/rolleyes.gif[/img] (BTW, that's not an annoyed eyeroll, that's a "look up" eyeroll) Edited by taby
0

Share this post


Link to post
Share on other sites
The irrationality of pi is not exactly what the problem is. There are many rational numbers that cannot be expressed exactly in floating-point formats either, like 1/3 or 0.1.
1

Share this post


Link to post
Share on other sites
mayby you are using degrees instead of radians if you use degrees you must multiply angle by pi/180

const float imopi = 0.017453292519943295769236907684886;


so then you should write this Cos = cos( angle* imopi);
-2

Share this post


Link to post
Share on other sites
[quote name='___' timestamp='1337855254' post='4942856']const float imopi = 0.017453292519943295769236907684886;[/quote]

Not only has the problem been well-diagnosed to be [i]not this[/i], but (appropriately enough) that constant has far more digits of precision than are typically representable in a float.
0

Share this post


Link to post
Share on other sites
[quote name='alvaro' timestamp='1337643825' post='4942034']
The irrationality of pi is not exactly what the problem is. There are many rational numbers that cannot be expressed exactly in floating-point formats either, like 1/3 or 0.1.
[/quote]

Edit: sicrane brought me up to speed with your logic regarding 0.1. It's all obvious now that what does not possess infinite non-zero placeholders right of the decimal point in base 10 may have infinite non-zero placeholders right of the binary point in base 2. Thanks!

I vote for the next version of IEEE fp to be in base pi. Problem solved! I'm kidding. :)
0

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  
Followers 0