I am currently echoing a number like this:
<?php echo $enterprise_platinum_price ?>
The problem is that the number normally has a decimal place such as 19.44 or 13.353
I need to display the full number but without the decimal point or any of the numbers behind it. I know that you can round to the full number in PHP but I don't ever want it to round up. If the only way to do this is with rounding, I need it to always round down...
Use the math floor function to round downward.
$a = floor(1.99); // $a = 1
You can also do it without rounding using number_format. There's many, many more ways, but I think the floor() option is the shortest for you.
$a = number_format(1505.99, 0, '', ''); // $a = 1505
Related
I'm building a site where people can exchange coins (site currency) into Bitcoin. The problem I'm having is that for some reason when I multiply the $btcprice with 3 or less the echo is really weird... for your sake this is the code that matters:
<?php
// get 0,01 usd in bitcoins into a variable
$btcprice = file_get_contents('https://blockchain.info/tobtc?currency=USD&value=0.01');
$valueInBTC = 4 * $btcprice;
echo $valueInBTC;
?>
Anything that's 4 or higher will work, but if you try to multiply this with 3 or less it gets weird. For example this:
<?php
// get 0,01 usd in bitcoins into a variable
$btcprice = file_get_contents('https://blockchain.info/tobtc?currency=USD&value=0.01');
$valueInBTC = 3 * $btcprice;
echo $valueInBTC;
?>
Will echo 7.959E-5
I just don't understand what the problem is...
The result you are getting is not an error. It is simply in a formatting you don't expect / know yet. 7.959E-5is exactly the same as 0.00007959 it is just a different way of writing it down. Think of it as 7.959E-5 = 7.959 × (10 ^ (-5)) = 0.00007959. It is called Scientific notation (E notation). In cumputation / science this notation is used, because you can show very large or very small (as in your case) numbers with less digits (it is just shorter to write).
To get the number in other formattings use the php function sprintf().
As you are handling bitcoin values, you shouldn't be formatiing the numbers until just for output. With bitcoins you always deal with very small numbers and you will soon meet precision problems if you try and calculate with formatted floating point numbers.
In most cases this is a formatting issue. You can simply use printf
printf("%.2f",$valueInBTC);
Another good option is to use number_format();
Eg:
$number = 1234.5678;
// english notation without thousands separator
$english_format_number = number_format($number, 2, '.', '');
// 1234.57
I have a question regarding number formating in PHP.
I have a variable called "average", which is simply an average of a few values. To make it clear I rounded the number to 2 decimal places. Now the problem is, that if the average is for example 2.90, it only shows 2.9. Is there any way of displaying 2 decimal places always? I though I could do it by multiplying the number by 100, rounding it to zero d.p. and then divide by 100 again, but that seems a bit overcomplicated if there is an easier way of doing it.
Maybe you can try the number_format(float $number [, int $decimals = 0 ])?
For more information, take a look at http://php.net/manual/en/function.number-format.php
Format the output with printf
printf("%.1f", $num); // prints 1 decimal place
printf("%.2f", $num); // prints 2 decimal places
I have a situation where all records in a CSV I'm parsing are currency, but the values are not separated by a decimal point. So for instance, value '1234' is actually '12.34', and '12345' is '123.45'.
I'm struggling to find a way to manually convert these values into decimals. I can't user number_format, because it will give me an output like so:
$original_num = 1234;
$formatted_num = number_format($original_num, '2', '.', '');
$formatted_num = 1234.00; //Output
The other issue is that sometimes I may have a value like '436257.5' after I combine two numbers, which is actually '436.2575' so I can't just manually push in a '.' two places from the end of the string. Should I consider formatting it differently while I'm parsing the file?
Assuming you're using integers to always represent decimals with 2 places of precision after the decimal point, you just divide with 100 to insert the dot in the right place.
What do you mean, "combine"? You mean multiply? You should renormalise after each multiplication, and never get into a situation where you're representing decimals of differing precisions (unless you keep track of the precision, which you can do but it's pain in the ass and normally unnecessary).
function multiply($a, $b) {
return round($a * $b / 100);
}
function format($a) {
return sprintf("%.2f", $a / 100);
}
Since number_format() function always adds 2 00 as decimal, you can divide the value by 100.
number_format($original_num/100,2);
I've been wrestling with PHP's ceil() function giving me slightly wrong results - consider the following:
$num = 2.7*3; //float(8.1)
$num*=10; //float(81)
$num = ceil($num); //82, but shouldn't this be 81??
$num/=10; //float(8.2)
I have a number which may have any number of decimal places, and I need it rounded up to one decimal place.
i.e 8.1 should be 8.1, 8.154 should be 8.2, and 8 should be left as 8.
How I've been getting there is to take the number, multiply by 10, ceil() it, then divide by ten but as you can see I'm getting an extra .1 added in some circumstances.
Can anyone tell my why this is happening, and how to fix it?
Any help greatly appreciated
EDIT: had +=10 instead of *=10 :S
EDIT 2:
I didn't explicitly mention this but I need the decimal to ALWAYS round UP, never down - this answer is closest so far:
rtrim(rtrim(sprintf('%.1f', $num), '0'), '.');
However rounds 3.84 down to 3.8 when I need 3.9.
Sorry this wasn't clearer :(
Final Edit:
What I ended up doing was this:
$num = 2.7*3; //float(8.1)
$num*=10; //float(81)
$num = ceil(round($num, 2)); //81 :)
$num/=10; //float(8.1)
Which works :)
This is more than likely due to floating point error.
http://support.microsoft.com/kb/42980
http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html
http://joshblog.net/2007/01/30/flash-floating-point-number-errors/
http://en.wikipedia.org/wiki/Floating_point
You may have luck trying this procedure instead.
<?php
$num = 2.7*3;
echo rtrim(rtrim(sprintf('%.1f', $num), '0'), '.');
Floats can be a fickle thing. Not all real numbers can be properly represented in a finite number of binary bits.
As it turns out, a decimal section of 0.7 is one of those numbers (comes out 0.10 with an infinity repeating "1100" after it). You end up with a number that's ever so slightly above 0.7, so when you multiply by 10, you have a one's digit slightly above 7.
What you can do is make a sanity check. Take you float digit and subtract it's integer form. If the resulting value is less than, say, 0.0001, consider it to be an internal rounding error and leave it as-is. If the result is greater than 0.0001, apply ceil() normally.
Edit: A fun example you can do if you're on windows to show this is to open up the built in calculator application. Put in "4" then apply a square root function (with x^y where y=0.5). You'll see it properly displays "2". Now, subtract 2 from it and you'll see that you don't have 0 as a result. This is caused by internal rounding errors when it attempted to compute the square root of 4. When displaying the number 2 earlier, it knew that those very distant trailing digits were probably a rounding error, but when those are all that's left, it gets a bit confused.
(Before anybody gets onto me about this, I understand that this is oversimplified, but nonetheless I consider it a decent example.)
Convert your number to a string and ceil the string.
function roundUp($number, $decimalPlaces){
$multi = pow(10, $decimalPlaces);
$nrAsStr = ($number * $multi) . "";
return ceil($nrAsStr) / $multi;
}
The problem is that floating point numbers are RARELY what you expect them to be. Your 2.7*3 is probably coming out to be something like 81.0000000000000000001, which ceil()'s up to 82. For this sort of thing, you'll have to wrap your ceil/round/floor calls with some precision checks, to handle those extra microscopic differences.
Use %f instead of %.1f.
echo rtrim(rtrim(sprintf('%f', $num), '0'), '.');
Why not try this:
$num = 2.7*3;
$num *= 100;
$num = floor($num);
$num /= 10;
$num = ceil($num);
$num /= 10;
Got a math calculation problem.
$a = 34.56
$b = 34.55
$a do some calculation to get this figure
$b is doing rounding to the nearest 0.05 to get this figure
what happens is
$c = $b - $a
supposedly it be -0.01, but I echo out the $c, which shows -0.00988888888888
I try to use number_format($c, 2), but the output is 0.00,
how can I make sure $a and $b is exactly 2 decimals, no hidden number at the back.
in my php knowledge, number_format is only able to format the display, but the value is not really 2 decimal,
I hope I can get help from here. This really frustrated me.
Try sprintf("%.2f", $c);
Floating point numbers are represented in IEEE notation based on the powers of 2, so terminating decimal numbers may not be a terminating binary number, that's why you get the trailing digits.
As suggested by Variable Length Coder, if you know the precision you want and it doesn't change (e.g. when you're dealing with money) it might be better to just use fixed point numbers i.e. express the numbers as cents rather than dollars
$a = 3456;
$b = 3455;
$c = $b - $a;
sprintf ("%.2f", $c/100.0);
This way, you won't have any rounding errors if you do a lot of calculations before printing.
Use round():
$c = round($b - $a, 2);
Note: you can also choose the rounding mode as appropriate.
Edit: Ok I don't get what sprintf() is doing that number_format() isn't:
$c = number_format($b - $a, 2);
vs
$c = sprintf("%.2f", $b - $a);
?
You can very neatly sidestep all of these issues simply by using the bcmath library.
Just remember to read the documentation and be careful whether you are passing arguments as strings or as numeric datatypes.
You've run into one of the traps of floating point numbers; that they cannot always represent exact decimal fractions. If you want exact decimal values, you're better off using integers and then dividing by the precision you want at the end.
For example, if you're doing calculations in floats represeting Dollars (or your favorite currency), you may want to actually do your calculations in integer cents.
Native Calculation:
$a = 34.56;
$b = 34.55;
$c = $b - $a; // -0.010000000000005
Works as expected (! use always BC functions for real number calculations, the issue is for all C based platforms):
$a = '34.56';
$b = '34.55';
$c = bcsub($b, $a, 4); // -0.0100
I also ran into this issue recently when doing calculations with floats. For example, I had 2 floats that when subtracted and formatted, the value was -0.00.
$floatOne = 267.58;
$floatTwo = 267.58;
$result = number_format($floatOne - floatTwo, 2);
print $result; //printed a string -0.00
What I did was:
$result = abs($floatOne - $floatTwo);// Made the number positive
print money_format('%i', $result); // printed the desired precision 0.00
In my solution I know that floatOne will never be less than floatTwo.
The money_format function is only defined if the system has strfmon capabilities, Windows does not.
If still somebody reach this page with similar problems where floating number subtraction causes error or strange values.
I want to explain this problem with a bit more details. The culprit is the floating point numbers.
And different operating systems and different versions of programming languages can behave differently.
To illustrate the problem, I will explain why with a simple example below.
It is not directly related to PHP and it is not a bug.
However, every programmer should be aware of this issue.
This problem even took many lives two decades ago.
On 25 February 1991 this problem in floating number calculation in a MIM-104 Patriot missile battery prevented it intercepting an incoming Scud missile in Dhahran, Saudi Arabia, contributing to the death of 28 soldiers from the U.S. Army's 14th Quartermaster Detachment.
But why it happens?
The reason is that floating point values represent a limited precision. So, a value might
not have the same string representation after any processing. It also
includes writing a floating point value in your script and directly
printing it without any mathematical operations.
Just a simple example:
$a = '36';
$b = '-35.99';
echo ($a + $b);
You would expect it to print 0.01, right?
But it will print a very strange answer like 0.009999999999998
Like other numbers, floating point numbers double or float is stored in memory as a string of 0's and 1's. How floating point differs from integer is in how we interpret the 0's and 1's when we want to look at them. There are many standards how they are stored.
Floating-point numbers are typically packed into a computer datum as the sign bit, the exponent field, and the significand or mantissa, from left to right....
Decimal numbers are not well represented in binary due to lack of enough space. So, uou can't express 1/3 exactly as it's 0.3333333..., right? Why we can't represent 0.01 as a binary float number is for the same reason. 1/100 is 0.00000010100011110101110000..... with a repeating 10100011110101110000.
If 0.01 is kept in simplified and system-truncated form of 01000111101011100001010 in binary,when it is translated back to decimal, it would be read like 0.0099999.... depending on system (64bit computers will give you much better precision than 32-bits). Operating system decides in this case whether to print it as it sees or how to make it in more human-readable way. So, it is machine-dependent how they want to represent it. But it can be protected in language level with different methods.
If you format the result, echo number_format(0.009999999999998, 2); it will print 0.01.
It is because in this case you instruct how it should be read and how precision you require.
Now you can use this 'round' function to get 2 decimal values.
$a = '34.5638';
$b = round($a,2)
34.56 // result