php binary to decimal - php

I am connecting to an api that returns binary string data that I need to convert to decimal format with php. The data comes across in four-part chunks like "66 50 235 133" and should translate to some value around 50.00 (not sure exactly what the decimal value should be, but should be close to 50).
So, I need to convert the binary string "66 50 235 133" to a decimal value around 50.
I have read the pack and unpack function pages on php.net, but am unsure if this is the correct function to use and which formats to use (signed/unsigned,endian,etc). Thanks for any help you can offer or any help point me in the right direction!

Might be:
$input = '66 50 235 133';
$value = unpack('g', implode('', array_map('chr', explode(' ', $input))));
// outputs -2.2117755600046E-35
Or:
$input = '66 50 235 133';
$value = unpack('G', implode('', array_map('chr', explode(' ', $input))));
// outputs 44.729999542236
Depending on the Endianness.
I suspect it's the later, if you think this number is close to 50.00.

Related

Looking for a PHP smart format number

I am looking for a solution for a smart number formatting in PHP.
For example we have 2 numbers below and we need 4 digits after decimal:
1.12345678
0.00002345678
Using normal number formatting, here are the results:
1.1234 // Looking good
0.0000 // No good
Can we make it keep going until there are 4 non-zero digits? If it can return 0.00002345, perfect!!!
Many thanks!!!
Might be overkill and the pattern could be optimized, but for fun; get optional 0s AND 4 NOT 0s after the .:
preg_match('/\d+\.([0]+)?[^0]{4}/', $num, $match);
echo $match[0];
To round it we can get 5 digits after the 0s and then format it to the length of that -1 (which will round):
preg_match('/\d+\.([0]+?[^0]{5})/', $num, $match);
echo number_format($match[0], strlen($match[1])-1);
For $num = '1234.000023456777'; the result will be 1,234.00002346 and the $matches will contain:
Array
(
[0] => 1234.000023456
[1] => 000023456
)
So this is the code I made to slove this:
$num = 0.00002345678;
$num_as_string = number_format($num,PHP_FLOAT_DIG,'.','');
$zeros = strspn($num_as_string, "0", strpos($num_as_string, ".")+1);
echo number_format($num, (4+$zeros), '.', '');
It converts the float number to a string, checks how many zeros exist after the decimal point and then does a number format with the extra zeros accounted for.
Note that it may break if your float is too big, you can change PHP_FLOAT_DIG to a number larger that may fix that.

PHP Convert a dec to a bit array with a predefined length

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

how to convert binary into base64? [duplicate]

I know this is a pretty silly question, but I don't know what to do.
I have an arbitrary binary number, say,
1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111
I want to convert it to Base 64 using PHP - and every way I try gives me a different result. Even different online converters convert it differently:
http://home2.paulschou.net/tools/xlate/
http://convertxy.com/index.php/numberbases/
PHP's base_convert only works up to base36, and base64_encode expects a string.
What do I do?
UPDATE: I implemented the solution functions suggested by #binaryLV, and it did work well.
However, I compared the results to PHP's built-in base_convert. It turned out that base_convert to base36 returns shorter values that the custom base64 function! (And yes, I did prepend a '1' to all the binary numbers to ensure leading zeros aren't lost).
I have noticed, too, that base_convert is quite innacurate with large numbers. So I need is a function which works like base_convert, but accurately and, preferably, up to base 64.
Length of a string in example is 160. It makes me think that it holds info about 160/8 characters. So,
split string into parts, each part holds 8 binary digits and describes single character
convert each part into a decimal integer
build a string from characters, that are made from ASCII codes from 2nd step
This will work with strings with size n*8. For other strings (e.g., 12 binary digits) it will give unexpected results.
Code:
function bin2base64($bin) {
$arr = str_split($bin, 8);
$str = '';
foreach ( $arr as $binNumber ) {
$str .= chr(bindec($binNumber));
}
return base64_encode($str);
}
$bin = '1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111';
echo bin2base64($bin);
Result:
kDICQIMBEFjDBxwMBJiAASBYwgc=
Here's also function for decoding it back to string of binary digits:
function base64bin($str) {
$result = '';
$str = base64_decode($str);
$len = strlen($str);
for ( $n = 0; $n < $len; $n++ ) {
$result .= str_pad(decbin(ord($str[$n])), 8, '0', STR_PAD_LEFT);
}
return $result;
}
var_dump(base64bin(bin2base64($bin)) === $bin);
Result:
boolean true
PHP has a built in base 64 encoding function, see documentation here. If you want the decimal value of the binary string first use bin2dec, there are similar functions for hexadecimals by the way. The documentation is your friend here.
[EDIT]
I might have misunderstood your question, if you want to convert between actual bases (base 2 and 64) use base_convert
$number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
echo base64_encode ($number);
This is if you want the exact string be converted into Base 64.
To convert a binary number (2 base) to a 64 base use the base_convert function.
$number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
base_convert ($number , 2, 64);

PHP float with 2 decimal places: .00

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.

Convert a binary number to Base 64

I know this is a pretty silly question, but I don't know what to do.
I have an arbitrary binary number, say,
1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111
I want to convert it to Base 64 using PHP - and every way I try gives me a different result. Even different online converters convert it differently:
http://home2.paulschou.net/tools/xlate/
http://convertxy.com/index.php/numberbases/
PHP's base_convert only works up to base36, and base64_encode expects a string.
What do I do?
UPDATE: I implemented the solution functions suggested by #binaryLV, and it did work well.
However, I compared the results to PHP's built-in base_convert. It turned out that base_convert to base36 returns shorter values that the custom base64 function! (And yes, I did prepend a '1' to all the binary numbers to ensure leading zeros aren't lost).
I have noticed, too, that base_convert is quite innacurate with large numbers. So I need is a function which works like base_convert, but accurately and, preferably, up to base 64.
Length of a string in example is 160. It makes me think that it holds info about 160/8 characters. So,
split string into parts, each part holds 8 binary digits and describes single character
convert each part into a decimal integer
build a string from characters, that are made from ASCII codes from 2nd step
This will work with strings with size n*8. For other strings (e.g., 12 binary digits) it will give unexpected results.
Code:
function bin2base64($bin) {
$arr = str_split($bin, 8);
$str = '';
foreach ( $arr as $binNumber ) {
$str .= chr(bindec($binNumber));
}
return base64_encode($str);
}
$bin = '1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111';
echo bin2base64($bin);
Result:
kDICQIMBEFjDBxwMBJiAASBYwgc=
Here's also function for decoding it back to string of binary digits:
function base64bin($str) {
$result = '';
$str = base64_decode($str);
$len = strlen($str);
for ( $n = 0; $n < $len; $n++ ) {
$result .= str_pad(decbin(ord($str[$n])), 8, '0', STR_PAD_LEFT);
}
return $result;
}
var_dump(base64bin(bin2base64($bin)) === $bin);
Result:
boolean true
PHP has a built in base 64 encoding function, see documentation here. If you want the decimal value of the binary string first use bin2dec, there are similar functions for hexadecimals by the way. The documentation is your friend here.
[EDIT]
I might have misunderstood your question, if you want to convert between actual bases (base 2 and 64) use base_convert
$number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
echo base64_encode ($number);
This is if you want the exact string be converted into Base 64.
To convert a binary number (2 base) to a 64 base use the base_convert function.
$number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
base_convert ($number , 2, 64);

Categories