| Ultrashock Forums
cos and sin not working properly?? |
|||
![]() |
||||
| Search this Thread | Thread Tools | Display Modes |
|
|
|||||||||||||||||||||||||
![]() |
Ultrashock Member Comments:
|
|
2003-08-30
#2 |
||
|
Last edited by andreaskr : 2003-08-30 at 04:19.
|
|
|
|
2003-08-30
#3 |
||
|
Last edited by Dickee : 2003-09-03 at 23:25.
I realize that andreaskr was only using 'int' to create the example, but it should never be used when dealing with cos and sin values, both of which range between -1<0<1 ... for any values other than the extremes of 1 and -1, the result when applying 'int' will be 0. The problem is actually caused by the 'IEEE floating point error' which is well documented on the net. The examples below show that subtracting 1e-16 has no effect, but 1e-15 does affect the result. Jon Bradley has formulated an algorithm to deal with epsilon in Flash posted here. I'm not sure why he has used 256 for the 's' fraction and loop counter, rather than 308.25... (close to Flash's MIN_VALUE/MAX_VALUE power as I've used in my experimentation, resulting in different max/min 'close to 0' values) ... no doubt that it has to do with the bitwise operations (256 = 2^8) that are causing the rounding error. Since his formal name has a baccalaureate appendage and mine does not, let's go with Jon's work! ![]() Code:
// ----------------------------------------
// Machine Error : Epsilon
// Find the smallest E such that 1 + E > 1
//
// Author: Jon Bradley
// ----------------------------------------
// ----------------------------------------
// Machine Error : Epsilon
// Find the smallest E such that 1 + E > 1
//
// Author: Jon Bradley
// ----------------------------------------
function getEpsilon()
{
var s = 1/Math.pow(10, 256);
for (var i = 0; i<256; i++)
{
s *= 10;
if (1 + s > 1)
{
break;
} else
{
epsilon = s;
}
}
Math.EPSILON = epsilon;
return epsilon;
}
e = getEpsilon();
trace(e);
Code:
// 1. Your example for the angle 180°:
("1. "+trace(Math.sin(Math.PI))) // 1.22460635382238e-16
// 2. when 'int' is applied:
trace("2. "+(int(1.22460635382238e-16))); // 0
// 3. however, when the angle is 90°
trace("3. "+(Math.sin(.5*Math.PI))) // 1
// 4. when your 180° result is applied to an angle of 90°:
trace("4. "+(Math.sin(.5*Math.PI)-Math.sin(Math.PI))) // 1
// 5. same thing with the actual result plugged in:
trace("5. "+(Math.sin(.5*Math.PI)-1.22460635382238e-16)) // 1
// 6. however, when 1e-15 is subtracted, the reult is different:
trace("6. "+(Math.sin(.5*Math.PI)-1.22460635382238e-15)) // 0.999999999999999
// 7. when 'int' is applied to #6:
trace("7. "+int((Math.sin(.5*Math.PI)-1.22460635382238e-15))) // 0
// 8. which when dealing with cos and sin, are very different results
trace("8. "+(int(-0.999999999999999))); // 0
// 9. and the same happens with the positive case
trace("9. "+int((1-(1e-15)))); // 0
// more examples
trace("10. "+(Math.sin(2*Math.PI))); // -2.44921270764475e-16
trace("11. "+(Math.cos(2*Math.PI))); // 1
trace("12. "+(int(Math.sin(2*Math.PI)))); // 0
trace("13. "+(Math.cos(2*Math.PI)-Math.sin(2*Math.PI))); // 1
trace("14. "+(int(Math.cos(2*Math.PI)-Math.sin(2*Math.PI)))); // 1
trace("15. "+(Math.cos(2*Math.PI)-Math.sin(2*Math.PI)-.1)); // 0.9
trace("16. "+(int(Math.cos(2*Math.PI)-Math.sin(2*Math.PI)-.1))); // 0
trace("17. "+(int(Math.cos(2*Math.PI)-Math.sin(2*Math.PI)-1e-15))); // 0
trace("18. "+(int(Math.cos(2*Math.PI)-Math.sin(2*Math.PI)-1e-16))); // 1
// all around the circle
trace("19. "+(Math.sin(.5*Math.PI))); // 6.12303176911189e-17
trace("20. "+(Math.cos(.5*Math.PI))); // 1.22460635382238e-16
trace("21. "+(Math.sin(Math.PI))); // -2.44921270764475e-16
trace("22. "+(Math.cos(Math.PI))); // -1
trace("23. "+(Math.sin(1.5*Math.PI))); // -1
trace("24. "+(Math.cos(1.5*Math.PI))); // -1.83690953073357e-16
trace("25. "+(Math.sin(2*Math.PI))); // -2.44921270764475e-16
trace("26. "+(Math.cos(2*Math.PI))); // 1
// one more showing 'int' misuse
trace("27. "+(Math.sin(1.5*Math.PI)+.1)); // -.9
trace("28. "+(int(Math.sin(1.5*Math.PI)+.1))); // 0
|
|
|
|
2003-08-30
#4 |
||
|
great info thanks alot...you learn more everyday
|
|
|
|
2003-09-03
#5 |
||
|
Last edited by Dickee : 2003-09-04 at 08:48.
Hey Matrix!
That's probably the worst reason to go with anything.
So, you feel that my hoed-road, the 'School of Hard Knocks', is the preferred path to follow, rather than the hallowed halls of post-secondary masochism? I'll keep that in mind! ![]() <edit> If you're having trouble following this ... Matrix posted twice with some valuable information and links to info on the LAPACK algorithm, but for some reason his posts were deleted from the thread. ???! I couldn't follow the Fortran script, I'm afraid, so I googled a JavaScript example from: http://www3.telus.net/thothworks/MachEps.html .. which when tested in the Flash environment, returned the same results as the page's display, differing from the results of Jon's 'getEpsilon()' function, which returns 9.99999999999999e-17 on my Athlon XP-2200 (Windows): Code:
dbleEpsilon = function() {
var temp1,temp2,mchEps;
temp1 = 1.0;
do {
mchEps = temp1;
temp1 /= 2;
temp2 = 1.0+temp1;
} while (temp2>1.0);
return mchEps;
};
trace (dbleEpsilon()); // 2.22044604925031e-16
BTW, I emailed Jon to get his view of the situation, but so far, no reply. Richard |
|
|
|
2003-09-04
#6 |
||
|
The IEEE floating point arithmatic library defines a certain specified way of calculating floating point operations. The Double Precision (64 bit) Machine Epsilon is defined as 2^-53 or approximately 1.11 x 10^-16. Your results of double-epsilon return approximately twice that value, whice is accurate. This epsilon algorithm used may underestimate the true error by a factor p(n) <= 10n. This means that although you get the same results in both places, there's no real way to know whether or not your calculation is accurate with that algorithm within a boundary of approximately 1x10-16. Good job hunting that equation down. It results in the direct calculation of the machine error - very good. Even then, there's a very good chance that running mathematical operations under the limit I provided, but above the limit this algorithm generates will not be stable. best, Jon B. |
|
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|


5 comments
| 862 views



Linear Mode
try this..
...and the result will be 0.