I'm having a hard time to figure out, how to format a range of number correctly.
Lets say I have an array with the following values:
array( 1, 2, 001, 02, 012 );
How can I change the output of each value to fit the following format?
0 => 1
1 => 2
2 => 0.01
3 => 0.2
4 => 0.12
I'm not looking for a loop ( this is just for explanation), just a way to format the number correctly.
This is the way PHP interpret Integer you can see you have no leading zeros on Integer ;-)
var_dump(array( 1, 2, 001, 02, 012 ));
array(5) {
[0]=>int(1)
[1]=>int(2)
[2]=>int(1)
[3]=>int(2)
[4]=>int(10)
}
The only way to solve it is converting it to a String.
Related
This question already has an answer here:
PHP, sort, sort_flags
(1 answer)
Closed 2 years ago.
I have an array to sort as
$numbers = array(24, 19, 3, 16, 56, 8, 171);
sort($numbers, SORT_STRING);
print_r($numbers);
And thus when i sort the array i get the result as
(
[0] => 16
[1] => 171
[2] => 19
[3] => 24
[4] => 3
[5] => 56
[6] => 8
)
How does the SORT_STRING works can anybody explain it to me?
SORT_STRING will compare character by character as in a word. So letter A is "higher" (or lower, your choice) than B, B > C.
1 > 2, 2 > 3, 11 > 12 and so on.
So in your case, when comparing 24 with 19, it will compare 1 with 2 and then order.
As a second example, when comparing 19 with 16, first will compare 1 with 1, which is equal, then compare 9 with 6, making 6 (and 16) a higher order.
More info here: PHP, sort, sort_flags
If you want to dig deeper, this is the link for the PHP source code.
This is the line where it choices the sort algorithm depending on the sort flag:
https://github.com/php/php-src/blob/50765075db6b6d5a9597589601c59f743f6ee9c8/ext/standard/array.c#L502
And here where it execute the comparison/sort:
https://github.com/php/php-src/blob/50765075db6b6d5a9597589601c59f743f6ee9c8/ext/standard/array.c#L207
And then it will call a zend operator:
https://github.com/php/php-src/blob/5430a466ff31422b436df076581d8345531db975/Zend/zend_operators.c
The SORT_STRING compare items as strings. You can find more detail here: https://www.php.net/manual/en/function.sort.php
A simple example is when you sort your files or directories on you computer: the sorting is alphabetical order.
This works as an ascending numeric values for the first digits(as 1 in 16) of all the numbers and after finishing them all,the pointer goes towards the digit next to it (as 6 in 16) and this is how it works so basically it arranges the digits from the left most digit and then goes on arranging them by the preceeding ones(right).
For example: comparing between 16 and 171
As both the numbers have their left-most digits as 1 it sorts it numbers based on their next digits(the right ones).
And thus by following the rule you get an result array as
(
[0] => 16
[1] => 171
[2] => 19
[3] => 24
[4] => 3
[5] => 56
[6] => 8
)
I’m re-factoring an application, and one of the database tables stores days of the week in columns. Each day can either be “on” or “off”.
The notion of on and off makes me think this data could be more succinctly represented as bits. But I’ve not worked with raw bits as a data type before.
The application is written in PHP. I’ve seen bits used to store header values here. There are then “helper” constants (HEADER_X_FORWARDED_ALL and HEADER_X_FORWARDED_ALL that act as “pre-configurations” for all headers being used, or a sub-set being used for AWS ELB-like environments (where some headers are not sent, so are “off”).
So I have a couple of questions using this data type for representing days of the weeks:
How would I store the final bit value in MySQL? As in the column data type, length etc.
How would I check a day is “on”? If I have the value 0b0100000, how do I determine using bitwise operators that Tuesday is “on”?
How do I “set” days to persist the value in the database? So if I have checkboxes in the UI that submits the values as an array, how would I convert something like:
Array
(
[days] => Array
(
[Monday] => 0
[Tuesday] => 1
[Wednesday] => 0
[Thursday] => 0
[Friday] => 0
[Saturday] => 0
[Sunday] => 0
)
)
…to a bit value like 0b0100000, again using bitwise operators?
If someone could point me in the right direction of getting started with working with bit values in PHP, I’d be most grateful!
You could store the decimal values of the selected days. So as a really basic example:
/**
* Keys are ISO-8601 numeric representation
* of the days of the week
*/
$days = [
1 => 0b0000001, // Monday => 1
2 => 0b0000010, // Tuesday => 2
3 => 0b0000100, // Wednesday => 4
4 => 0b0001000, // Thursday => 8
5 => 0b0010000, // Friday => 16
6 => 0b0100000, // Saturday => 32
7 => 0b1000000, // Sunday => 64
];
You'd just loop and check if the day's bit is set in the value (bitwise and):
// The value you'd store in your database
$mondayToFriday = 31; // 1 + 2 + 4 + 8 + 16
foreach ($days as $n => $v) {
/**
* Get the day's name using strftime (has locale capability)
* strtotime("Sunday +n days") would work with ISO-8601 day
* numbers or PHP's date("w") (0 - 6 / Sunday - Saturday)
*/
$day = strftime("%A", strtotime("Sunday +{$n} days"));
echo "{$day}: " . (($v & $mondayToFriday) ? "Y" : "N") . PHP_EOL;
}
As for your checkboxes, you could just build the binary string from the state of each day (0 or 1), and convert it to decimal using bindec() (the order in which they appear in the array is important, you'd need to ensure that they're correctly mapped to their corresponding day's value).
Given your example input, and the days in this example, the following would work:
$dec = bindec(strrev(implode("", $input["days"])));
Hopefully that'll push you in the right direction.
Here's an example to play with
Is it possible to convert from numeric to an alphanumeric code like this:
a
b
c
d
..
z
1
2
3
4
..
aa
ab
ac
ad
..
az
a1
a2
a3
a4
..
aaa
aab
aac
aad
..
aaz
aa1
aa2
etc.
I'm trying to convert large numbers to smaller length alphanumeric strings.
Don't know why you want to do this specifically, but try changing the base from 10 to something like 32;
base_convert($number, 10, 32);
Then to convert back
base_convert($number, 32, 10);
As someone else pointed out - for very large numbers this may not work.
If you need to be able to handle very large numbers, check out this link:
How to generate random 64-bit value as decimal string in PHP
You can use base_convert() for changing the base of your number from 10 (decimal) to 36 (26 latin letters plus 10 arabic numerals).
The result will differ from your given example list. You have used the digits abc..xyz012..789, base_convert will use a diffent order 012..789abc..xyz.
// convert decimal to base36
echo base_convert($number_dec, 10 , 36);
// convert base36 to decimal
echo base_convert($number_b36, 36 , 10);
Translation
dec base36
0 0
1 1
...
9 9
10 a
11 b
...
34 y
35 z
36 10
37 11
..
45 19
46 1a
...
1295 zz
1296 100
1297 101
You could use dechex to convert the number to hex
http://php.net/manual/en/function.dechex.php
For example:
1000000 => f4240
1000001 => f4241
1000002 => f4242
1000003 => f4243
1000004 => f4244
1000005 => f4245
1000006 => f4246
1000007 => f4247
1000008 => f4248
1000009 => f4249
1000010 => f424a
1000011 => f424b
1000012 => f424c
1000013 => f424d
1000014 => f424e
1000015 => f424f
1000016 => f4250
1000017 => f4251
1000018 => f4252
1000019 => f4253
1000020 => f4254
To convert back, just use hexdec
http://php.net/manual/en/function.hexdec.php
base64_encode();
and for decode use
base64_decode();
Both dechex() and base_convert() will fail with large numbers. They are limited by the maximum size and precision of int and float types internally used during conversion.
The http://php.net/manual/pt_BR/function.base-convert.php discussion has some nice helper functions (see 2, 3) that can avoid this problem by using BC-functions to do the math. The BC extension can deal with arbitrarily large numbers.
I have an array:
$test =array('49'=> '-0','51'=> '-0','50'=> '0','53'=> '-1.69','55'=> '0','57'=> '-2','59'=> '-6','60'=> '-12','65'=> '0','66'=> '0','67'=> '21.69','69'=> '0','70'=> '0','71'=> '0',);
echo "\n".'===== First Method ========';
echo "\n\n".print_r($test);
echo "\n array_sum: ".array_sum($test);
echo "\n\n".'===== Second Method ========';
$total = 0;foreach($test as $value) $total += $value;
echo "\n foreach:".$total."\n";
the result is
gd#gd:~/Desktop$ php test.php
===== First Method ========Array
(
[49] => -0
[51] => -0
[50] => 0
[53] => -1.69
[55] => 0
[57] => -2
[59] => -6
[60] => -12
[65] => 0
[66] => 0
[67] => 21.69
[69] => 0
[70] => 0
[71] => 0
)
1
array_sum: 3.5527136788005E-15
===== Second Method ========
foreach:3.5527136788005E-15
it is wrong, the result should be 0, not 3.5527136788E-15, how to fix it ?
This is just your standard floating point arithmetic precision error.
php -r "echo -1.69 + -2 + -6 + -12 +21.69;"
3.5527136788005E-15%
You can fix it by using ints rather than floats. For example, if you always expect 2 digits of precision, multiply all your numbers by 100, round them off to ints, sum them, and divide by 100.
php -r "echo (-169 + -200 -1200 +2169 + -600) / 100;"
0%
You are doing array_sum with strings. Remove the quotes on the values, or covert them to integers before using array_sum - I imagine it is converting the strings to integers incorrectly - only on my phone so can't check specifics.
Hope this helps.
Why not just give the values as floating point numbers rather than enclosing them in quotes. That would basically make it a string summation and strange result is expected. I think in before PHP version 4.something it used to convert the string to numbers. It might especially be problem with decimal numbers.
This is just an example of floating point imprecision. It's impossible to represent .69 exactly in binary (much like it's impossible to represent 1/3 exactly in decimal).
If you need exact numbers, you can look into using the bcmath php extension.
I have some bar code numbers in an array. PHP seems to be rounding the barcodes which start with leading zeros. How do I stop this happening and keep the numbers as they were? Code I am using is below:
$array = array(5032227448124,5060028999989,5010121096504,5060028999996,5016254104864,5016402052788,8422248036986,0000003798720,0000003735503,0000003798713);
echo '<pre>';
print_r($array);
echo '</pre>';
This echos the following, as you can see the last four bar codes which feature leading zeros have been changed and had their leading zeros removed. These numbers are always 13 digits long and are padded with zeros.
Array
(
[0] => 5032227448124
[1] => 5060028999989
[2] => 5010121096504
[3] => 5060028999996
[4] => 5016254104864
[5] => 5016402052788
[6] => 8422248036986
[7] => 31
[8] => 1030979
[9] => 31
[10] => 1031004
)
You need to quote them as strings if they arent a number (integer, float, exponent).
The obvious, easy, and also likely wrong answer is to make them strings.
The better answer is to use printf()/sprintf() to pad with zeroes:
printf('%013d', 12345); // output: 0000000012345
MySQL also has a handy LPAD() function:
SELECT LPAD(12345, 13, 0) // output 0000000012345
Here's an easy way to convert your values to padded strings:
$array = array_map(function ($e){return str_pad($e, 13, "0", STR_PAD_LEFT);}, $array);
In the end I just needed to put double quotes around each barcode number e.g.
$array = array("5032227448124","5060028999989","5010121096504","5060028999996","5016254104864","5016402052788","8422248036986","0000003798720","0000003735503","0000003798713");