Related
I'm getting confused on how to do a simple thing, perhaps someone can help me.
At one point of my code I convert a bit array with 10 alarms (0 or 1) to a decimal and save it.
At another point I load the decimal and want to convert it back to a bit array.
This works however the bit array should be always have a length of 10 even if the decimal length is not 10 bites.
See my code:
// Convert array to dec:
$alarms = array(0,0,1,0,0,0,1,0,0,0);
$str = implode("", $alarms);
$dec = bindec($str);
// Convert back to bit array:
$bin = decbin($dec);
echo $bin;
The result of this code is:
10001000
But should be:
0010001000
Thanks!
Here's an idea of how you might implement this.
<?php
// Input array of bits
$inBits = [0,0,1,0,0,0,1,0,0,0];
// Convert to decimal value
$value = bindec(implode('', $inBits));
// Convert back to string of 0/1, adding padding as needed.
$outBitStr = str_pad(decbin($value), count($inBits), '0', STR_PAD_LEFT);
var_dump(implode('', $inBits) === $outBitStr); // TRUE
I have got the following code:
$strNumber = "4.0";
$float = 4.0;
I am aiming to print the sum the two variables above and get 8.0 but weirdly when converting $strNumber to a float, it prints 4. The same holds true to $float - when vardumping it prints 4. As result, I have in the end 8, instead. I researched for hours for a solution but I was not successful.
I guess I could do print_r((float)$strNumber + $float . ".0"; , though, those variables will change and so it will give me an unwanted outcome. Is there actually a solution? I would very grateful if someone could help me.
Your sum is not, in fact, becoming a whole number. It is only being displayed that way. PHP has very flexible and intuitive type-casting. By putting (float) in front of the string, you can cast it to that type.
$strNumber = "4.0";
$floatNumber = (float)$strNumber;
$float = 4.0;
$sum = $floatNumber + $float;
print_r(number_format($sum, 1, '.', ','));
However, this is not necessary at all as the casting is so automatic in PHP that the following is the same thing:
$strNumber = "4.0";
$float = 4.0;
$sum = $strNumber + $float;
print_r(number_format($sum, 1, '.', ','));
Bottom line, even if you type-cast "4.0" to (float), it's still going print "4" because that's a matter of how it prints, not the data type. Use number_format() to make it look the way you want.
See here for more: https://www.php.net/manual/en/language.types.type-juggling.php
Is there a built-in/neat way to format a number (just like number_format does), but without any rounding ups/downs?
For instance, number 1234.234 should be formatted as 1,234.234 and another number 1234 should be formatted as 1,234 (i.e. without any trailing .000)
You can define simple custom function for that:
<?php
function custom_number_format($number, $decimal = '.')
{
$broken_number = explode($decimal, $number);
if (isset($broken_number[1]))
return number_format($broken_number[0]) . $decimal . $broken_number[1];
else
return number_format($broken_number[0]);
}
$n1 = '1234.234';
$n2 = '1234';
echo custom_number_format($n1);
echo '<br>';
echo custom_number_format($n2);
?>
Output is:
1,234.234
1,234
Based on the arhey's answer
TLDR ;)
You can use number_format to format the number to a fixed-width format, then use rtrim twice to remove trailing zeroes, and dot.
rtrim(rtrim(number_format($number, 3, '.', ','), '0'), '.')
Starting from the last character, rtrim removes it while it is one of those given. In our case, we remove trailing dots, then we remove an eventual trailing zero.
rtrim(rtrim(number_format(1234.123, 3, '.', ','), '0'), '.')
// returns 1,234.123
rtrim(rtrim(number_format(1234.12, 3, '.', ','), '0'), '.')
// returns 1,234.12 (1,234.120, trimmed to 1234.12)
rtrim(rtrim(number_format(1234, 3, '.', ','), '0'), '.')
// returns 1,234 (1,234.000, trimmed to 1234)
rtrim(rtrim(number_format(1200, 3, '.', ','), '0'),'.')
// returns 1,200 (1,200.000, trimmed to 1200., trimmed to 1200)
Formal form, and discussion about the parameters (notably the decimals count)
rtrim(rtrim(number_format($number, <N>, '<D>', ''), '0'), '<D>')
Where :
D is the decimal separator. To avoid locale-formatting problems, explicitly specify it
N is the maximum digits you number can have.
If you know all your numbers will have less than 3 digits, go and take N=3.
What if you don't know how many decimals are at most ? Well, things are getting more complex.
It may worth recalling (as stated in the PHP documentation) that floats are stored :
with a precision (a number of digits, without distinction whether they are before or after the decimal separator), not a number of decimals
and in their binary form, not their decimal one, and that can lead to rounding errors when reaching precision limit.
For example, floor((0.1+0.7)*10) will usually return 7 instead of the
expected 8, since the internal representation will be something like
7.9999999999999991118....
So there is no universal good value, you'll have to choose it depending on the usual scale of your data.
And that explains why there is no built-in function for that : PHP can't choose for you.
You can use function:
<?php
function getNumberFormat($number) {
$numberAr = explode('.', (string)$number);
$count = 0;
if (2 === count($numberAr)) {
$count = strlen($numberAr[1]);
}
return number_format($number, $count, ',', '.');
}
$test1 = 1234.234;
$test2 = 1234;
echo getNumberFormat($test1); //1,234.234
echo getNumberFormat($test2); //1,234
I really liked arhey's answer, but later realized it has a major flaw. A number like 2100 will get converted to 2,1 instead of 2,100.
Below is how I ended up modifying it.
public function formatDecimal($number)
{
$stringVal = strval($number); //convert number to string
$decPosition = strpos($stringVal, ".");
if ($decPosition !== false) //there is a decimal
{
$decPart = substr($stringVal, $decPosition); //grab only the decimal portion
$result = number_format($stringVal) . rtrim($decPart, ".0");
}
else //no decimal to worry about
{
$result = number_format($stringVal);
}
return $result;
}
It's not as succinct a solution as I was hoping, but in my case I put it into a view helper (I'm using ZF2) and so it's just one simple function call in my view.
Hope this is helpful for someone!
rtrim(number_format(1234.234, 3),'.0');
rtrim(number_format(1234, 3),'.0');
Let's begin with that there's no decimal type in PHP. There's float only.
And if you know how float works, then you know that it's usually not possible to store exact decimal value that you think you have, but it's an approximation. That's because you can't express most of decimal numbers in binary system.
Therefore if you say:
$number = 1234.234;
Then you have a float that is close to this value. The real value is:
1234.23399999999992360244505107402801513671875
Therefore PHP can't just guess how do you want to round it. It needs to be specified explicitly.
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
When I do this typecasting:
(float) '0.00';
I get 0. How do I get 0.00 and still have the data type as a float?
A float doesn't have 0 or 0.00 : those are different string representations of the internal (IEEE754) binary format but the float is the same.
If you want to express your float as "0.00", you need to format it in a string, using number_format :
$numberAsString = number_format($numberAsFloat, 2);
As far as i know there is no solution for PHP to fix this. All other (above and below) answers given in this thread are nonsense.
The number_format function returns a string as result as written in PHP.net's own specification.
Functions like floatval/doubleval do return integers if you give as value 3.00 .
If you do typejuggling then you will get an integer as result.
If you use round() then you will get an integer as result.
The only possible solution that i can think of is using your database for type conversion to float. MySQL for example:
SELECT CAST('3.00' AS DECIMAL) AS realFloatValue;
Execute this using an abstraction layer which returns floats instead of strings and there you go.
JSON output modification
If you are looking for a solution to fix your JSON output to hold 2 decimals then you can probably use post-formatting like in the code below:
// PHP AJAX Controller
// some code here
// transform to json and then convert string to float with 2 decimals
$output = array('x' => 'y', 'price' => '0.00');
$json = json_encode($output);
$json = str_replace('"price":"'.$output['price'].'"', '"price":'.$output['price'].'', $json);
// output to browser / client
print $json;
exit();
Returns to client/browser:
{"x":"y","price":0.00}
0.00 is actually 0. If you need to have the 0.00 when you echo, simply use number_format this way:
number_format($number, 2);
You can show float numbers
with a certain number of decimals
with a certain format (localised)
i.e.
$myNonFormatedFloat = 5678.9
$myGermanNumber = number_format($myNonFormatedFloat, 2, ',', '.'); // -> 5.678,90
$myAngloSaxonianNumber = number_format($myNonFormatedFloat, 2, '.', ','); // -> 5,678.90
Note that, the
1st argument is the float number you would like to format
2nd argument is the number of decimals
3rd argument is the character used to visually separate the decimals
4th argument is the character used to visually separate thousands
Use the number_format() function to change how a number is displayed. It will return a string, the type of the original variable is unaffected.
try this
$nom="5695.5";
number_format((float)($nom), 2, '.', ','); // -> 5,695.50
$nom="5695.5215";
number_format((float)($nom), 2, '.', ','); // -> 5,695.52
$nom="5695.12";
number_format((float)($nom), 0, '.', ','); // -> 5,695
//use round()
$nom="5695.12";
number_format((float)round($nom), 2, '.', ','); // -> 5,695.00
$nom="5695.52";
number_format((float)round($nom), 2, '.', ','); // -> 5,696.00
you can try this,it will work for you
number_format(0.00, 2)
A number of comments on this page have missed the fundamental point that the question is ill-formed. Floating point is a binary representation, designed for efficient calculations; it fundamentally has no notion of decimal digits of any sort.
So asking this:
How do I get "0.00" instead of "0" and still have the data type as a float?
Is like asking this:
How do I get "deux" instead of "zwei" and still have the language as English?
Whether you specify the input as "2", or "2.0", or "2.000000000", if you ask for a floating point value, what will be stored in memory is this (in IEEE 754 double-precision):
0100000000000000000000000000000000000000000000000000000000000000
If you convert to an integer, the value stored in memory is this (assuming a 64-bit system):
0000000000000000000000000000000000000000000000000000000000000010
(Note that "integer" in this context is not just a synonym for "whole number", it is a specific data type, with its own rules for how values should be represented in memory.)
By contrast, the string "2" would look like this:
00110010
And the string "2.00" would look like this:
00110010001011100011000000110000
(In a PHP program, there would actually be additional information in memory, such as an indicator of the type, but that's not really relevant here.)
So, the question can only be answered by rephrasing it as a conversion: given the input of a floating point number, how do I choose a string representation which has a fixed number of decimals.
As others have pointed out, the answer to that is to use number_format.
The question doesn't mention JSON, but several comments do, so I will also point out that PHP's json_encode function has an option JSON_PRESERVE_ZERO_FRACTION, which will format a floating point number that happens to be a whole number with a trailing ".0", for instance:
$example = ['int' => 2, 'float' => 2.0];
echo json_encode($example);
# => {"int":2,"float":2}
echo json_encode($example, JSON_PRESERVE_ZERO_FRACTION);
# => {"int":2,"float":2.0}
Again, note that this is a string representation of the value.
You can use round function
round("10.221",2);
Will return 10.22
You can use floatval()
floatval()
try this
$result = number_format($FloatNumber, 2);
You can use this simple function.
number_format ()
$num = 2214.56;
// default english notation
$english_format = number_format($num);
// 2,215
// French notation
$format_francais = number_format($num, 2, ',', ' ');
// 2 214,56
$num1 = 2234.5688;
// English notation with thousands separator
$english_format_number = number_format($num1,2);
// 2,234.57
// english notation without thousands separator
$english_format_number2 = number_format($num1, 2, '.', '');
// 2234.57
When we format any float value, that means we are changing its data type to string. So when we apply the formatting on any amount/float value then it will set with all possible notations like dot, comma, etc. For example
(float)0.00 => (string)'0.00',
(float)10000.56 => (string) '10,000.56'
(float)5000000.20=> (string) '5,000,000.20'
So, logically it's not possible to keep the float datatype after formatting.