I have a question.
I am using php to generate a number based on operations that a user has specified
This variable is called
$new
$new is an integer, I want to be able to round $new to a 12 digit number, regardless of the answer
I was thinking I could use
round() or ceil()
but I believe these are used for rounding decimel places
So, I have an integer stored in $new, when $new is echoed out I want for it to print 12 digits. Whether the number is 60 billion or 0.00000000006
If i understand correctly
function showNumber($input) {
$show = 12;
$input = number_format(min($input,str_repeat('9', $show)), ($show-1) - strlen(number_format($input,0,'.','')),'.','');
return $input;
}
var_dump(showNumber(1));
var_dump(showNumber(0.00000000006));
var_dump(showNumber(100000000000000000000000));
gives
string(12) "1.0000000000"
string(12) "0.0000000001"
string(12) "999999999999"
Related
I have let's say 0.00001004 or 0.00001
I am trying to choose and how decimal places to prune off and turn both of those so it returns 0.00001 both times.
I do not want it to round the number in anyway.
I've tried this but it is not giving me the desired results.
function decimalFix($number, $decimals) {
return floatval(bcdiv($number, 1, $decimals));
}
echo decimalFix(0.00001, 5); // returns "0"
Does anyone know what I can do? I can't have any rounding involved and I need it to return it as a float and not a string.
I don't know why you're so committed to losing precision, but here's some math to make that particular mistake in the way you wish to make it.
$derp = 0.000016;
function derp_round($derp, $len) {
$mul = pow(10, $len);
return floor($derp * $mul)/$mul;
}
var_dump(
$derp,
number_format($derp, 5),
sprintf("%.5f", $derp),
sprintf("%.5f", round($derp, 5, PHP_ROUND_HALF_DOWN)),
sprintf("%.5f", derp_round($derp, 5))
);
Output:
float(1.6E-5)
string(7) "0.00002"
string(7) "0.00002"
string(7) "0.00002"
string(7) "0.00001"
There's a function that does exactly this in the first comment on the PHP documentation for floor(). I'll copy it here in case it disappears from there, but credits go to seppili_:
function floordec($zahl,$decimals=2){
return floor($zahl*pow(10,$decimals))/pow(10,$decimals);
}
Use it like:
$number = 0.00001004;
$rounded = floordec($number, 5);
var_dump($rounded); // float(0.00001)
Edit: There's a comment further down on that page by Leon Grdic that warns about float precision and offers this updated version:
function floordec($value,$decimals=2){
return floor($value*pow(10,$decimals)+0.5)/pow(10,$decimals);
}
Usage is the same.
I want my variable's first decimal to always be rounded up. For example:
9.66 goes to 9.7
9.55 goes to 9.6
9.51 goes to 9.6
9.00000001 goes to 9.1
How do I do this?
Use round() with an optional precision and round type arguments, e.g.:
round($value, 1, PHP_ROUND_HALF_UP)
The optional second argument to round() is the precision argument and it specifies the number of decimal digits to round to. The third optional argument specifies the rounding mode. See the PHP manual for round for details.
Using round() does not always round up, even when using PHP_ROUND_HALF_UP (e.g. 9.00001 is not rounded to 9.1). You could instead try to use multiplication, ceil() and division:
ceil($value * 10.0) / 10.0
Since these are floating-point values, you might not get exact results.
I made couple tests and suggest the following answer with test cases
<?php
echo '9.66 (expected 9.7) => '.myRound(9.66).PHP_EOL;
echo '9.55 (expected 9.6) => '.myRound(9.55).PHP_EOL;
echo '9.51 (expected 9.6) => '.myRound(9.51).PHP_EOL;
echo '9.00000001 (expected 9.1) => '.myRound(9.00000001).PHP_EOL;
echo '9.9 (expected ??) => '.myRound(9.9).PHP_EOL;
echo '9.91 (expected ??) => '.myRound(9.91).PHP_EOL;
function myRound($value)
{
return ceil($value*10)/10;
}
I'm not a php programmer so will have to answer in "steps". The problem you have is the edge case where you have a number with exactly one decimal. (e.g. 9.5)
Here's how you could do it:
Multiply your number by 10.
If that's an integer, then return the original number (that's the edge case), else continue as follows:
Add 0.5
Round that in the normal way to an integer (i.e. "a.5" rounds up).
Divide the result by 10.
For step (2), sniffing around the php documentation reveals a function bool is_int ( mixed $var ) to test for an integer.
You will need a custom ceil() function, your requirements cannot be satisfied by the default function or by the round.
Use this: online test
You can use this technique. Just explode the given number / string, get the number which is next value / digit of the .. after getting this you need to increment that value and check if the value is greater than 9 or nor, if then divide that and add the carry to the first portion of the main number.
$var = '9.96';
$ar = explode(".", $var);
$nxt = substr($ar[1], 0, 1) + 1;
if($nxt > 9){
$tmp = (string) $nxt;
$num = floatval(($ar[0] + $tmp[0]).".".$tmp[1]);
}
else
$num = floatval($ar[0].".".$nxt);
var_dump($num); // float(10)
Is there any function that easily echos an integer that is 15+ digits long?
The only way I've managed is like this:
$num = 123456789012345;
$num = number_format($num);
$num = str_replace(',', '', $num);
echo $num;
But even this way it is only accurate up to 17 digits. After the 16th digit the number isn't printed accurately (because as a float it starts getting inaccurate - see here).
EDIT: From the answers below I wrote ini_set('precision',40); and then echoed $num straight. All this did was to, simply put, not show the decimal point in the float number. And again after the 16th digit it starts getting inaccurate.
I also tried the other suggestion of changing it into an array and then iterating through it with str_split($num); and again the numbers were inaccurate from the 17th digit on!
The simplest solution would be to convert the integer into a string. I've tried:
$num = (string)$num;
//and
$num = strval($num);
But neither change anything and they act as if as they remained as an int??
My question is specifically why are the conversions into strings not working. Is there a way to turn the number into a string? Thanks
The only solution I can think of is changing the precision of floats in the php.ini
ini_set('precision', 25);
I don't know where you get those large numbers from, but I'd suggest a look into bc functions too!
The last thing I thought of is using the explode function to split the string into an array and interate through it.
EDIT: When all suggestions failed, your only choices are to check out the BC Math and/or GMP functions as well as MoneyMath. The BigInteger package should also do the trick, which uses GMP and BC.
Well, you see, it's not an "int" as you claimed :)
echo PHP_INT_MAX; // echoes 9223372036854775807
$n = 9223372036854775807;
echo $n; // echoes 9223372036854775807
$n = 9223372036854775808;
echo $n; // echoes 9.2233720368548E+18
Setting precision to something greater, as manniL said, does the trick.
ini_set("precision", 50);
$n = 9223372036854775808;
echo $n; // echoes 9223372036854775808
this might be a stupid question but I have searched again and again without finding any results.
So, what I want is to show all the decimal places of a number without knowing how many decimal places it will have. Take a look at this small code:
$arrayTest = array(0.123456789, 0.0123456789);
foreach($arrayTest as $output){
$newNumber = $output/1000;
echo $newNumber;
echo "<br>";
}
It gives this output:
0.000123456789
1.23456789E-5
Now, I tried using 'number_format', but I don't think that is a good solution. It determines an exact amount of decimal places, and I do not know the amount of decimal places for every number. Take a look at the below code:
$arrayTest = array(0.123456789, 0.0123456789);
foreach($arrayTest as $output){
$newNumber = $output/1000;
echo number_format($newNumber,13);
echo "<br>";
}
It gives this output:
0.0001234567890
0.0000123456789
Now, as you can see there is an excess 0 in the first number, because number_format forces it to have 13 decimal places.
I would really love some guidance on how to get around this problem. Is there a setting in PHP.ini which determines the amount of decimals?
Thank you very much in advance!
(and feel free to ask if you have any further questions)
It is "impossible" to answer this question properly - because a binary float representation of a decimal number is approximate: "What every computer scientist should know about floating point"
The closest you can come is write yourself a routine that looks at a decimal representation of a number, and compares it to the "exact" value; once the difference becomes "small enough for your purpose", you stop adding more digits.
This routine could then return the "correct number of digits" as a string.
Example:
<?php
$a = 1.234567890;
$b = 0.123456789;
echo returnString($a)."\n";
echo returnString($b)."\n";
function returnString($a) {
// return the value $a as a string
// with enough digits to be "accurate" - that is, the value returned
// matches the value given to 1E-10
// there is a limit of 10 digits to cope with unexpected inputs
// and prevent an infinite loop
$conv_a = 0;
$digits=0;
while(abs($a - $conv_a) > 1e-10) {
$digits = $digits + 1;
$conv_a = 0 + number_format($a, $digits);
if($digits > 10) $conv_a = $a;
}
return $conv_a;
}
?>
Which produces
1.23456789
0.123456789
In the above code I arbitrarily assumed that being right to within 1E-10 was good enough. Obviously you can change this condition to whatever is appropriate for the numbers you encounter - and you could even make it an optional argument of your function.
Play with it - ask questions if this is not clear.
I'm trying to parse a csv file with PHP and everything works ok as long as I keep the numbers as strings. However, since I'd like to sum the values of nested arrays I need them to be numbers.
There are three values that I need to fix:
$column[1] is cost and contains decimals (ex. 20.30)
$column[2] is clicks (ex. 15)
$column[3] is conversions (ex. 3)
If I try using floatval() or intval() on the values they return 0.
Example: $cost = intval($column[1]);
I saw somewhere in another thread that they use trim() or ltrim() to clean up the value. So I tried that on my numbers...
$cost = intval(trim($column[1]));
$clicks = intval(trim($column[2]));
$conversions = intval(trim($column[3]));
But that just gives me the first digit of the number, so I get this..
cost : 2 (instead of 20.30)
clicks : 1 (instead of 15)
conversions: 3 (is actually correct)
I've tried using both "." and "," as decimals.
Really can't figure this one out. Any help I can get is much appreciated!
Structure:
array(4) {
[0]=> string(21)"avslag l�n"[1]=> string(11)"31.32"[2]=> string(3)"1"[3]=> string(5)"0 "
}
array(4) {
[0]=> string(45)"l�na trots kronofogden"[1]=> string(11)"99.12"[2]=> string(3)"2"[3]=> string(5)"0 "
}
array(4) {
[0]=> string(59)"g�r gymnasiet men vill ta l�n"[1]=> string(11)"33.86"[2]=> string(3)"1"[3]=> string(5)"0 "
}
array(4) {
[0]=> string(45)"l�n till enskild firma"[1]=> string(11)"80.07"[2]=> string(3)"1"[3]=> string(5)"1 "
}
You could type cast the values as follows:
$cost = (double) $column[1];
$clicks = (int) $column[2];
$conversions = (int) $column[3];
http://www.php.net/manual/en/language.types.type-juggling.php
if you are looking to format the double then do the following:
$cost = number_format($column[1], 2);
EDIT: Thanks for the var_dump, try this.
$cost = (double) $column[0][1];
$clicks = (int) $column[0][2];
$conversions = (int) $column[0][3];
You are trying to interact with a 2D array as if it was 1 dimensional.
use number format with floatval
$cost = floatval(column[1]);
$cost = number_format($cost, 2);
http://php.net/manual/en/function.number-format.php
if value of $column[1] is "20.30" you can simply use it for calculations as php automatically converts string to numbers when you do arthritic calculations.
ex:
$column[1]="20.30";//$column[1] is string.
$column[1]*=1.0;//Now $column[1] is an float variable..
You can also use type conversion like:
$a=(float)$column[1]*1;
And so on..
I could be wrong...in which case I have a gambling problem apparently...but I'm fairly certain you're trying to do all these conversions on an actual array(), not a string.
Your printout shows 4 different arrays, each with key/value pairs. And all of these are linked into $column.
If I had to guess, which I shouldn't do on Stack Exchange, I would say try this:
$column[1][1]
instead of what you have now as
$column[1]
I've been up quite a long time though so grain of salts are to be taken here.