The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

It is most probably due to php has a set decimal length for any float value you have worked on. Even if it does not show in the var_dump the variable $r has a bunch of decimal zero values attached. The number depends on the php.ini settings.

Try to restrict the value to a desired amount of decimals when using it. You can for example use: sprintf("&#37;01.1f", $r)
Please note that you should change the decimal number depending on the accuracy needed in your algorithm.

Interesting... Does sqrt return some other kind of variable than float or does php just have general problems with floats? Since .6/$r = 1 in this example echo(asin((float)((int) (.6 / $r)))) actually outputs the right answer, so if you type convert you can get away from this problem, but I guess that doesn't help you here though.
I can't help you solve this but I'm mighty interested myself in what causes this.

This is not a PHP issue with floating point precision, but a computer issue. Most decimal floating-point values simply cannot be accurately represented in binary. Fractions like 1/2 (0.5), 1/4 (0.25), 1/8 (0.125), etc (i.e. divide by a power of 2) can be, but others like 1/5 (0.2) cannot be, and still others can't even be accurately represented in decimal (e.g. 1/3 (0.33333...)), so you certainly can't expect binary to be able to handle them! When dealing with floating point numbers in any kind of computer system, you must be aware that the results will not always be what you expect, and will vary when you perform an identical operation on a different platform.

The most likely cause is an errant 1 way way waaaaaay down toward the end of the internal floating-point buffer. By converting to a string and back again you are essentially forcing a rounding error that, in this case, is fixing another rounding error. Another fix is to round the result of squaring $tx to e.g. 5 places; this latter solution is most often the fix used to solve such rounding errors.

Again, floating-point on computers is really really tricky, and is the reason for several integer-based libraries that aim to emulate floating-point while avoiding rounding errors; most such libraries use integers to represent floating-point numbers by dividing the integer by e.g. 1,000 when displaying, and otherwise are performing nothing but slightly modified integer arithmetic. If anyone is interested in such uber-geeky stuff I can post a more detailed explanation of the cause of rounding errors (such as what we are seeing here), as well as how the integer-based floating point libraries work.

Then why does it work with one float but not the other one returned from the sqrt();?

Because the last one has not been modified.

Originally Posted by kromey

This is not a PHP issue with floating point precision, but a computer issue. Most decimal floating-point values simply cannot be accurately represented in binary. Fractions like 1/2 (0.5), 1/4 (0.25), 1/8 (0.125), etc (i.e. divide by a power of 2) can be, but others like 1/5 (0.2) cannot be, and still others can't even be accurately represented in decimal (e.g. 1/3 (0.33333...)), so you certainly can't expect binary to be able to handle them! When dealing with floating point numbers in any kind of computer system, you must be aware that the results will not always be what you expect, and will vary when you perform an identical operation on a different platform.

Yes, in the end this is a computer issue, as you say a floating point will never be accurate due to how the computers work. Thanks for noteing it, its not always Im able to get the wording properly when writing a reply

However keep in mind that the floating point system inside php is modified to be more "accurate" since it allow you do decide when to cut the decimals so the issue is not as "extreme" as it could have been.

Though for best compability it is best to force the decimal length yourself instead of depending on that you will be able to change the php setting.

For those of you who are still confused, since the var_dump displays the same number.
Functions like var_dump has already performed the rounding, while when you use the same variable in a math operation it is used as "it is" (can for example in this case be: 0.5999999999999998223643160599749535322189)
When you then limit the decimals, the value will automatically be rounded to that amount of decimals.

Originally Posted by kromey

The most likely cause is an errant 1 way way waaaaaay down toward the end of the internal floating-point buffer. By converting to a string and back again you are essentially forcing a rounding error that, in this case, is fixing another rounding error.

The stored value is usally always slightly less than the value it should be (like the example above), in my experience its seldom higher. I.e. the floating point is usally always rounded up.

It seems that var_dump does indeed not output the complete value for $r, which causes the argument to the asin function to be larger than 1 and result in an error. It was easily fixed after I understood what was going on..

I've never seen a situation before where the rounding errors had such a big impact..

Heh, just play around with floating point arithmetic. Especially if you do a lot of operations on computed values. Each computation results in a little more error, and that builds up over time. Operations like square root compound a lot more error than e.g. multiplication or division. Keep it up and eventually you can end up being off by a whole lot more than a single bit way down at the end of the buffer.

@TheRedDevil
You're absolutely right that the stored value is almost always slightly less than the actual value, however in this case since we are subtracting the squared floating point (which is slightly less) from 1.0 (which can be represented with no error at all), we are in fact ending up slightly over the actual value, which is causing the arcsin function to return NAN because it is only valid from -1.0 to +1.0 and we're ever-so-slightly over +1.0. This is why the string conversion and explicit rounding both fix the problem in this instance.