unexpected result in php output with larger strings - php

I am trying to create a binary/hexadecimal converter to convert a denary(base 10) number/value into binary and hexadecimal.
It works fine so far for binary until the input from the form is greater than 11 digits and over(string length), ruffly as it seems to variety. after 11 digits it starts adding " - " into the outcome. Im not sure were this is coming from as I don't have an " - " in the code.
I wasn't sure if this was something to do with large integers as I saw some other questions on that topic(not in php however it was java, so not sure if there is something simpler in php)
That said I was under the impression that form inputs were always strings.
To test if a variable is a number or a numeric string (such as form input, which is always a string), you must use is_numeric(). - from : http://www.php.net/manual/en/function.is-float.php
(haven't yet got to hexadecimal but needed to mention it as some of the following code contains parts for it.)
here is the php code (note: I do check user input just not added it yet)
$inpu = $_POST['number'];
$numinput = $_POST['number'];
if (is_numeric($numinput))
{
while ($numinput >= 1)
{
$binary .= $numinput % 2;
$numinput = $numinput / 2;
}
$mult = strlen($binary) % 4;
echo gettype($numinput) . "<br />";
echo gettype($binary) . "<br />";
echo gettype($mult) . "<br />";
echo $mult . "<br />";
while ($mult < 4)
{
$binary.= "0";
$mult++;
}
$revbinary = strrev($binary);
echo $inpu . " in binary = " . $revbinary ;
echo "<br /> <br />";
echo chunk_split($revbinary, 4);
echo "<br />" . gettype($revbinary) . "<br />";
echo gettype($inpu) . "<br />";
}
else
{
if (is_numeric($numinput))
{
echo "$numinput is over the max value of 255";
}
else
{
echo "your entry is not a vaild number <br />";
echo $numinput;
}
}
Im not looking for completed version of this code as you would ruin my fun, I am just wondering why there is a "-" being entered after 11 digits or so. It also did't add the symbol before I added :
$mult = strlen($binary) % 4;
echo $mult . "<br />";
while ($mult < 4)
{
$binary.= "0";
$mult++;
}
This was to split the binary into 4s ( 0011 1101 0010 0110 ).
Edit: wondered if this would be useful:
echo gettype($numinput); result double
echo gettype($binary); result string
echo gettype($mult); result integer
gettype($revbinary); result string
echo gettype($inpu); result string
still trying to work this out myself.
Any advice is much appreciated Thanks

I would suggest simply using decbin() and dechex(). Those are functions included in php, which do exactly what you're trying to accomplish.
You might want to check if it is a number first (like you are already doing).
Then cast it to an integer (through intval()) and then apply decbin() and dechex()
http://php.net/manual/de/function.decbin.php
http://www.php.net/manual/de/function.dechex.php
http://php.net/manual/de/function.intval.php

Related

Division with php

Im trying to get out an average value from a vote function.
<?php
$file = file("textfile.txt");
$textfil = file_get_contents("textfile.txt");
$textfill = str_split($textfil);
echo "Number of votes: " . count($textfill) . "<br>";
$sum = 0;
foreach ($textfill as $vote) {
$sum = $sum + intval($vote);
}
echo "Average: " . $sum;
?>
Simple by substitute (+) with a (/), and even tried a (%). But still getting error message.
Would appreciate alot if anyone could help me out and tell me what im doing wrong.
/thanks
Edit
Sidenote: Please read an explanation under "First answer given" further down below.
This version will take into account any blank lines in a file, if the content looks like:
1
2
3
// <- blank line
Sidenote: Please provide a sample of your text file. A comment has already been given to that effect.
PHP
<?php
// first line not required
// $file = file("textfile.txt");
$textfil = file_get_contents("textfile.txt");
$textfill = array_filter(array_map("trim", file("textfile.txt")), "strlen");
echo "Number of votes: " . count($textfill) . "<br>";
$sum = 0;
foreach ($textfill as $vote) {
$sum += intval($vote);
}
$avg = $sum / count($textfill);
echo "Average: " . $avg;
?>
First answer given
Using the following in a text file: (since no example of file content was given)
5
5
5
IMPORTANT NOTE: There should not be a carriage return after the last entry.
produced
Number of votes: 5
Average: 3
which is false, since there are 3 entries in the text file.
explode() should be used, and not str_split()
The following using the same text file produced:
Number of votes: 3
Average: 5
which is correct. In simple mathematics, averages are done by adding all numbers then dividing them by how many numbers there are.
In this case it's 3 numbers (all 5's) added equals 15, divided by 3 is 5.
Sidenote: The first line is not required $file = file("textfile2.txt");
<?php
// first line not required
// $file = file("textfile.txt");
$textfil = file_get_contents("textfile.txt");
$textfill = explode("\n", $textfil);
echo "Number of votes: " . count($textfill) . "<br>";
$sum = 0;
foreach ($textfill as $vote) {
$sum += intval($vote);
}
$avg = $sum / count($textfill);
echo "Average: " . $avg;
?>
Footnotes:
If the average comes out to 8.33333 and you would like it to be rounded off to 8, use:
echo "Average: " . floor($avg);
If the average comes out to 8.33333 and would like it to be as 9 you would use:
echo "Average: " . ceil($avg);
ceil() function
floor() function
You may be mixing in stuff that can't be divided, like text, etc. I don't know what your text file looks like. intval may be having a problem with arrays. You may try:
foreach ($textfill as $vote) {
if(is_int($vote) {
$sum += $vote;
}
}
echo "Average: " . $sum;
Lower school math says:
foreach ($textfill as $vote) {
$sum += intval($vote);
}
$avg = $sum / count($textfill);
The average value is calculated by divide the sum with the number of votes. This line will print the average value:
echo "Average: " . $sum/count($textfill);

changing font makes + combine strings instead of adding values

Here is my code:
<?php
$num1 = 10;
$num2 = 15;
echo "<font color='red'>$num1 + $num2</font>" . "<br>";
?>
I expect it to equal "25", when I add a font color it equals "10 + 15". Why?
You cannot do math inside a string. Instead, close the string. perform your addition operation, and concatenate the result.
echo "<font color='red'>" . ($num1 + $num2) . "</font><br>";
As Orangepill wisely points out, this can be accomplished more efficiently like this:
echo "<font color='red'>",($num1 + $num2),"</font><br>";
change
echo "<font color='red'>$num1 + $num2</font>" . "<br>";
to
echo "<font color='red'>",($num1 + $num2),"</font><br>";
You need to concatenate your string otherwise math will not work
echo "<font color='red'>".($num1 + $num2)."</font>" . "<br>";

Convert EXIF data to how it should looks like

According to PHP, the EXIF information for a image is 20/10 for F-number, 51/10 for focal length, and 10/150 for exposure. This is not how these values should look like! It should looks like F/2 for F-number, 5, mm for focal length, and 1/150 for exposure. These values are just some examples! Please see this link for how I really mean how it should looks like. Note that I will not use any third party software! Just pure PHP.
Is it possible to convert these values (for example 20/10) to the real values (for example F/2) in PHP? If yes, how can I convert them?
Thanks in advance.
EDIT
The following code convert 150/10 to 150 seconds which is 2 minutes and 30 seconds. This is wrong because I took the photo with 15 seconds shutter. How can I make it to calculate to the correct amount of seconds?
list($d1, $d2) = str_split('/', 'P1220379.JPG');
if($d1 > 0 AND $d2 > 0) {
$e = $d1 / $d2;
} else {
$e = 'P1220379.JPG';
}
if($e < 1 AND $e > 0) {
$e = '1/'.round(1 / $e, 0).' sekunder';
} else {
$e = round($e, 1).' sekunder';
}
"drpain" on this link says
Please note that when resizing images with GD and most image
processing scripts or applications you will loose the EXIF
information.What I did as a workaround is book this information into
MySQL before I re-size images.
His little program below
<?php
$camera = cameraUsed("/img/myphoto.jpg");
echo "Camera Used: " . $camera['make'] . " " . $camera['model'] . "<br />";
echo "Exposure Time: " . $camera['exposure'] . "<br />";
echo "Aperture: " . $camera['aperture'] . "<br />";
echo "ISO: " . $camera['iso'] . "<br />";
echo "Date Taken: " . $camera['date'] . "<br />";
?>
does produce these numbers in correct format, according to him
Will display the following, depending on the data:
Camera Used: SONY DSC-S930
Exposure Time: 1/400
Aperture: f/4.3
ISO: 100
Date Taken: 2010:12:10 18:18:45
This is my solution in kotlin if anyone needs
fun convertShutterSpeed(value: String?): String {
if (value.isNullOrBlank()) {
return ""
}
val split = value.split("/")
val ed: Float = split[0].toFloat()
val ed1: Float = split[1].toFloat()
val fl = ed / ed1
return if (ed < 0) {
Math.round(1 / Math.pow(2.toDouble(), fl.toDouble())).toString() + "s"
} else {
"1/" + Math.round(Math.pow(2.toDouble(), fl.toDouble()))
}
}
And here are some tests
#Test
fun convertShutterSpeed() {
assertEquals("1/8", imageExif.convertShutterSpeed("3/1"))
assertEquals("1/10", imageExif.convertShutterSpeed("3321928/1000000"))
assertEquals("1/20", imageExif.convertShutterSpeed("4321928/1000000"))
assertEquals("1/125", imageExif.convertShutterSpeed("6965784f/1000000"))
assertEquals("1/250", imageExif.convertShutterSpeed("7965784/1000000"))
assertEquals("1/320", imageExif.convertShutterSpeed("8321928/1000000"))
assertEquals("1/400", imageExif.convertShutterSpeed("8643856/1000000"))
assertEquals("1/640", imageExif.convertShutterSpeed("9321928/1000000"))
assertEquals("1/800", imageExif.convertShutterSpeed("9643856/1000000"))
assertEquals("1/1000", imageExif.convertShutterSpeed("9965784/1000000"))
assertEquals("2s", imageExif.convertShutterSpeed("-1/1"))
assertEquals("6s", imageExif.convertShutterSpeed("-2584963/1000000"))
}
Values that I got is from Canon images, but it works for other camera models as well.

Reopened: PHP array_shift(); VS reset(); unset(); array_splice();

Reopened:
Since PHP is a server-side language I had the assumption that it didn't matter what browser I used, but apparently not so. I had only been using Google Chrome.
I installed WAMP on my local machine so I can test it locally to see if it did the same as my shared hosting account. Both codes worked the way they should (in Chrome mind you). Then I looked at the exact same code on my shared hosting -- one worked, the other didn't.
I called my shared hosting support and they tried to duplicate the issue and said they weren't finding it. So I tried it in Firefox with them on the line and in IE, lo and behold... it worked perfectly in both just like on WAMP.
This still isn't making much sense to me. I'm using PHP 5.3 on my shared hosting account with a well known hosting company but not getting anywhere because they can't really troubleshoot code. They can replicate the issue but can't answer why. I'm going to try to find out more in the next weeks and post an update as I know more.
What I'm trying to do is this:
Generate a range of numbers
Shuffle them into a random order
Copy that array of randomly ordered numbers into a session array
Get the first value of the array, delete that value, and shift all
the values down by one
Here's my issue:
I tried using array_shift(); and it worked fine the first run but each time I ran the code after it would remove the first two elements.
To test what was going on I tried to print the array first, do array_shift();, and then print the array again to see what happened.
Expected Results:
Run #1:
[0]=>5 [1]=>2 [2]=>1 [3]=>4 [4]=>3 //print_r($array);
//execute array_shift($array);
[0]=>2 [1]=>1 [2]=>4 [3]=>3 //print_r($array);
Run#2:
[0]=>2 [1]=>1 [2]=>4 [3]=>3 //print_r($array);
//execute array_shift($array);
[0]=>1 [1]=>4 [2]=>3 //print_r($array);
Actual Results:
Run #1:
[0]=>5 [1]=>2 [2]=>1 [3]=>4 [4]=>3 //print_r($array);
//execute array_shift($array);
[0]=>2 [1]=>1 [2]=>4 [3]=>3 //print_r($array);
Run#2:
[0]=>1 [1]=>4 [2]=>3 //print_r($array);
//execute array_shift($array);
[0]=>4 [1]=>3 //print_r($array);
My issue (cont.)
So then I tried using reset($array);, unset($array[0]);, and array_splice($array,1,0); as an alternative to array_shift($array); and it worked! Then I tried to compare them side by side
and cleaned up the code and now they are doing the opposite of each other. Sometimes reset, unset, and array_shift; will even jump through up to 7 cells in the array when called once. array_shift(); is working the way I want it to now but I want to know why. It's driving me nuts! If someone could please help me I'd be so appreciative.
Code Dump:
unset, reset, splice
<?php
session_start();
$min = A;
$max = S;
if((!isset($_SESSION['image'])) || ($_SESSION['image'] == null))
{
$numbers = range($min, $max); //set a range for all images
shuffle($numbers); //shuffle the order for randomness
$_SESSION['image'] = $numbers;
echo "<br />Current value: " . $_SESSION['image'][0] . "<br />";
print_r($_SESSION['image']);
reset($_SESSION['image']);
unset($_SESSION['image'][0]);
array_splice($_SESSION['image'],1,0);
echo "<br />New value: " . $_SESSION['image'][0] . "<br />";
echo "<br />1st exec<br />";
}
else
{
echo "<br />Current value: " . $_SESSION['image'][0] . "<br />";
print_r($_SESSION['image']);
reset($_SESSION['image']);
unset($_SESSION['image'][0]);
array_splice($_SESSION['image'],1,0);
echo "<br />New value: " . $_SESSION['image'][0] . "<br />";
echo "<br />2nd exec<br />";
}
?>
shift
<?php
session_start();
$min = A;
$max = S;
if((!isset($_SESSION['id2'])) || ($_SESSION['id2'] == null))
{
$numbers = range($min, $max); //set a range for all images
shuffle($numbers); //shuffle the order for randomness
$_SESSION['id2'] = $numbers;
echo "<br />Current value: " . $_SESSION['id2'][0] . "<br />";
print_r($_SESSION['id2']);
array_shift($_SESSION['id2']);
echo "<br />New value: " . $_SESSION['id2'][0] . "<br />";
echo "<br />1st execution<br />";
}
else
{
echo "<br />Current value: " . $_SESSION['id2'][0] . "<br />";
print_r($_SESSION['id2']);
array_shift($_SESSION['id2']);
echo "<br />New value: " . $_SESSION['id2'][0] . "<br />";
echo "<br />2nd execution<br />";
}
?>
To ultimately learn what's going on, I propose to register a tick-function. The tick-function can execute at each PHP statement execution.
Here's a simple one, which traces line/file of each statement (feel free to add further details):
// Execute at each single statement
declare(ticks=1);
// Function to get called at each executing statement
function logEachStatement() {
$traceInfo = debug_backtrace();
$lastActivation = $traceInfo[ count( $traceInfo ) - 1 ];
$info = "\n"
. $lastActivation[ 'line' ] . '#' . $lastActivation[ 'file' ]
;
$targetFile = dirname( __FILE__ ) . '/stmnt.log' );
file_put_contents( $targetFile, $info, FILE_APPEND );
}
// using a function as the callback
register_tick_function( 'logEachStatement', true );
While there are other options to track down the problem, this one does not require external infrastructure.
Assuming that you pasted the actual code, the only way for this to happen is if you made an unintentional intermediate request. It would be impossible for us to determine how or why this is the case with only the given information, though.
My suggestion is to use your browser dev tool of choice (e.g. Firebug) and monitor the network tab to make sure that only one request is being sent to the script. If this doesn't turn up your problem, add some simple debug logging, such as this:
$log = date('Y-m-d H:i:s')
. ' :: Request received from '
. $_SERVER['REMOTE_ADDR']
. "\n";
file_put_contents('/path/to/your/log/file', $log, FILE_APPEND);
Then check your log after your test to make sure only one entry was added.

Create a loop structure to display all integer values BETWEEN the smaller and larger number provided?

Working on a homework assignment and am stuck with this task: Create a loop structure to display all integer values BETWEEN the smaller and larger number provided. Not looking for just an answer in code form. Would appreciate an explanation as to how and why it works.
Data for the variables comes from users inputting a value between 1 and 100. I assume I will need a loop that will start with the lower of the two variables, count until it reaches the higher of the two variables, echo each integer in between and stop running. I am at a loss as to how to achieve this. I will also need a loop that will display only integers at certain intervals between the two numbers, such as only the multiples of five.
EDIT: Here is my own solution, curious if this is the best method? Seems simple enough.
if ( $num1 < $num2 )
for ($i=$num1+1; $i<$num2; $i++)
echo $i . "<br />";
else
for ($i=$num2+1; $i<$num1; $i++)
echo $i . "<br />";
Here is some of the assignment thus far:
<?php
//Assign user input to variables
$num1 = $_GET['firstNum'];
$num2 = $_GET['secondNum'];
//Determine if each number is odd or even, display results
if( $odd = $num1%2 )
echo "First number is an ODD Number <br />";
else
echo "First number is an EVEN Number </br />";
if( $odd = $num2%2 )
echo "Second number is an ODD Number <br />";
else
echo "Second number is an EVEN Number </br />";
//Determine if the first number is larger than, smaller than, or equal to the second number, display results
if ( $num1 == $num2 )
echo "First number is equal to second number <br />";
elseif ( $num1 > $num2 )
echo "First number is greater than second number <br />";
else
echo "First number is less than second number <br />";
//Create a loop structure to display all integer values BETWEEN the smaller and larger number provided
?>
if ( $num1 < $num2 )
for ($i=$num1+1; $i<$num2; $i++)
echo $i . "<br />";
else
for ($i=$num2+1; $i<$num1; $i++)
echo $i . "<br />";
this may not perfectly fit your need. but hope this helps.
$num_small=$num1;
$num_large=$num2;
$multiply=1;
for ($i=$num_small; $num_large<=$i; $i+$multiply) {
echo $i;
}

Categories