I need to round any non-integers up to the nearest integer, regardless of whether the number after the decimal place is >5 or not.
You can make use of the ceil($value) function in PHP to round up.
Similarly you can make use of floor() for rounding down.
Related
Can php handle extremely small numbers without rounding them? For example, when calculating exp(-99) + 1/2, php compute this to be 0.5. This is problematic if later I want to multiply the given result, instead of an extremely small number, it just gives half the number.
echo exp(-99) + 1/2 // Outputs 0.5
You're out of the range supported by floating point numbers.
On my platform (PHP floats are 64 bit) echo exp(-99); returns currectly 1.0112214926104E-43
That's because the exponential part is wide enought to represent e^-99
But as I add... echo exp(-99)+0.5; I get 0.5
The result you expect would be something with more than 50 decimal digits.
Double floats doesn't have a such large mantissa (usually the limit is around 18-20 decimals).
To answer your question, If you really need to do such math (handle extremely small numbers without rounding them) you could use PHP's arbitrary precision math extension:
http://php.net/manual/en/book.bc.php
24151.40 - 31891.10 = -7739.699999999997
I grab these two numbers from a MySQL table with the type as decimal(14,2)
24151.40
31891.10
It is saved exactly as stated above and it echos exactly like that in PHP. But the minute I subtract the second value from the first value, I get a number -7739.699999999997 instead of -7,739.7. Why the extra precision? And where is it coming from?
From an article I wrote for Authorize.Net:
One plus one equals two, right? How about .2 plus 1.4 times 10? That equals 16, right? Not if you're doing the math with PHP (or most other programming languages):
echo floor((0.2 + 1.4) * 10); // Should be 16. But it's 15!
This is due to how floating point numbers are handled internally. They are represented with a fixed number of decimal places and can result in numbers that do not add up quite like you expect. Internally our .2 plus 1.4 times 10 example computes to roughly 15.9999999998 or so. This kind of math is fine when working with numbers that do not have to be precise like percentages. But when working with money precision matters as a penny or a dollar missing here or there adds up quickly and no one likes being on the short end of any missing money.
The BC Math Solution
Fortunately PHP offers the BC Math extension which is "for arbitrary precision mathematics PHP offers the Binary Calculator which supports numbers of any size and precision, represented as strings." In other words, you can do precise math with monetary values using this extension. The BC Math extension contains functions that allow you to perform the most common operations with precision including addition, subtraction, multiplication, and division.
A Better Example
Here's the same example as above but using the bcadd() function to do the math for us. It takes three parameters. The first two are the values we wish to add and the third is the number of decimal places we wish to be precise to. Since we're working with money we'll set the precision to be two decimal palces.
echo floor(bcadd('0.2', '1.4', 2) * 10); // It's 16 like we would expect it to be.
PHP doesn't have a decimal type like MySQL does, it uses floats; and floats are notorious for being inaccurate.
To cure this, look into number_format, e.g.:
echo number_format(24151.40 - 31891.10, 2, '.', '');
For more accurate number manipulation, you could also look at the math extensions of PHP:
http://www.php.net/manual/en/refs.math.php
This has to do with general float / double precision rates, which scientifically relates to 1.FRACTAL * 2^exponential power. Being that there's a prefix of 1, there's technically no such thing as zero, and the closest value you can obtain to 0 is 1.0 * 2 ^ -127 which is .000000[127 0s]00001
By rounding off your answer to a certain precision, the round factor will give you a more precise answer
http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_round
I have a program that is giving me this number: 9.1466606511048E-8
I need to round that, using most obvious functions in PHP gives me 0.
That's because that number has a value of 0.000000091466606511048, which is very close to zero. Perhaps you need to be more specific about what sort of rounding you want.
How many decimals are you attempting to round to?
The number that you specified is the same as: 0.000000091466606511048
If you're using the round function without specifying to what decimal place you want to round, then it is going to round to zero because of the value.
I've tried
$x = cos(deg2rad($angle));
but it returns 6.12323399574E-17 when the angle is 90 degrees instead of 0.
I read that this is a floating point problem, but is there a workaround?
6.1E-17 is almost zero anyway[*]. If you need to actually compare the result to zero, in floating point math you should check that it's within a certain tolerance of the desired value, since most numbers can't be represented correctly.
$x = cos(deg2rad($angle));
$is_zero = (abs($x) < 1e-10);
Strictly speaking, of course, zero is actually a number that can be represented correctly in floating point. The real problem is that pi / 2.0 can't be, so the input to your cos function isn't "correct".
[*] To put that in context, taken as a proportion of 1 AU (the average distance from the Sun to the Earth) it is equivalent to 0.0092 millimeters, or about a tenth of the average width of a human hair...
6.12323399574E-17 is an extremely small floating point number (17 zeros after the decimal point followed by a 6), almost indistinguishable from 0. If you are dealing with floating points (as any cosine function must), you can't avoid issues like this. If you need to compare a floating point number to zero, you must do it with error bars (i.e. is this number within a certain range of values around zero), not absolute comparison, even with simpler functions than cosine. If you just need to do some math with the result (add it, multiply it, whatever), it will behave almost exactly like zero so you won't need to worry.
Try this
$x = round(cos(deg2rad($angle)), 3);
I am entering '35444650.00' as a float into my MySQL and it keeps reformatting to 35444648.00, any help welcome...
Floats only have a certain level of precision, you may be going beyond how precise a float data type can be. Try using a DOUBLE instead.
A float has 6 digits of precision. Use a double to get 15 or switch to a numeric(x,y). If you're interested, check out the storage requirements for MySQL for the different data types.
The MySQL manual claims that FLOAT, REAL, and DOUBLE PRECISION fields stores values as approximate and INTEGER, SMALLINT, DECIMAL, and NUMERIC fields stores values as exact.
I think best bet to overcome this precision issue is to use decimal.
Reference: http://dev.mysql.com/doc/refman/5.1/en/numeric-types.html
A higher precision alternative to float is DOUBLE. But looking at the example, I think the DECIMAL datatype might come in handy if the number of digits required after zero is small (around 2-4) and the number of digits before decimal is also small (around 10-12).
You are going past the level of precision possible. You need to define the float with more precision, i.e. "FLOAT(10,5)" would mean a float that can have 10 digits total with up to five after the decimal point.