PHP - Check for positive / negative numeric strings - php

I'd like to know what is the best way to check whether a numeric string is positive or negative. I am using this answer on S.O but I am not able to determine whether a number with decimals is + or -
For example :
function check_numb($Degree){
if ( (int)$Degree == $Degree && (int)$Degree > 0 ) {
return 'Positive';
} else {
return 'Negative';
}
}
print check_numb("+2"); // returns Positive
print check_numb("+2.0"); // returns Positive
print check_numb("+2.1"); // returns Negative ??
print check_numb("+0.1"); // returns Negative ??
print check_numb("-0.1"); // returns Negative
It seems when a decimal is added it returns false. How do you properly check for positive strings > +0.XX and negative < -0.XX which 2 decimals..
Thanks!

Considering the given input, why not :
$number = '+2,33122';
$isPositive = $number[0] === '+' ? 'Positive' : 'Negative';
// Positive
$number = '-0,2';
$isPositive = $number[0] === '+' ? 'Positive' : 'Negative';
// Negative
Here is a more generic code, working even if the sign is removed from your input :
function checkPositive ($number) {
if (!is_numeric(substr($number, 0, 1))) {
$sign = substr($number, 0, 1);
return $sign == '+';
}
return $number > 0;
}
$number = '+2,33122';
var_dump(checkPositive($number));
// true
$number = '-2,33122';
var_dump(checkPositive($number));
// false
$number = '2,22';
var_dump(checkPositive($number));
// true

Your problem is because: (int)"+2.1" == 2 and 2 != "+2.1". For ALL numbers, if it is < 0 it is negative and if it is > 0 it is positive. If it is == 0, then it is obviously 0 which is unsigned.
function check_numb($Degree){
if ( $Degree > 0 ) {
return 'Positive';
} elseif( $Degree < 0 ) {
return 'Negative';
}
}

Related

number_format without decimal argument

I would like to use the number_format() function without to specify the number of decimals. (If 2 decimals, display 2, if 5, display 5)
Is that possible?
Thanks a lot
You can calculate the number of decimals before you use numberformat and use that in the function.
$number = 50001/4;
If(strpos($number, ".") !== false){
// Is float
$decimals = strlen($number) - (strpos($number, ".")+1);
}Else{
// Is integer == no decimals
$decimals =0;
}
Echo number_format($number, $decimals, ',', ' ');
https://3v4l.org/DULp4
If this is really what you want, this may work even if this is totally useless
function numberOfDecimals($value)
{
if ((int)$value == $value)
{
return 0;
}
else if (! is_numeric($value))
{
// throw new Exception('numberOfDecimals: ' . $value . ' is not a number!');
return false;
}
return strlen($value) - strrpos($value, '.') - 1;
}
$number = 1.23456;
print number_format($number,numberOfDecimals($number));
credits : PHP: get number of decimal digits

PHP check if is integer

I have the following calculation:
$this->count = float(44.28)
$multiple = float(0.36)
$calc = $this->count / $multiple;
$calc = 44.28 / 0.36 = 123
Now I want to check if my variable $calc is integer (has decimals) or not.
I tried doing if(is_int()) {} but that doesn't work because $calc = (float)123.
Also tried this-
if($calc == round($calc))
{
die('is integer');
}
else
{
die('is float);
}
but that also doesn't work because it returns in every case 'is float'. In the case above that should'n be true because 123 is the same as 123 after rounding.
Try-
if ((string)(int) $calc === (string)$calc) {
//it is an integer
}else{
//it is a float
}
Demo
As CodeBird pointed out in a comment to the question, floating points can exhibit unexpected behaviour due to precision "errors".
e.g.
<?php
$x = 1.4-0.5;
$z = 0.9;
echo $x, ' ', $z, ' ', $x==$z ? 'yes':'no';
prints on my machine (win8, x64 but 32bit build of php)
0.9 0.9 no
took a while to find a (hopefully correct) example that is a) relevant to this question and b) obvious (I think x / y * y is obvious enough).
again this was tested on a 32bit build on a 64bit windows 8
<?php
$y = 0.01; // some mambojambo here...
for($i=1; $i<31; $i++) { // ... because ...
$y += 0.01; // ... just writing ...
} // ... $y = 0.31000 didn't work
$x = 5.0 / $y;
$x *= $y;
echo 'x=', $x, "\r\n";
var_dump((int)$x==$x);
and the output is
x=5
bool(false)
Depending on what you're trying to achieve it might be necessary to check if the value is within a certain range of an integer (or it might be just a marginalia on the other side of the spectrum ;-) ), e.g.
function is_intval($x, $epsilon = 0.00001) {
$x = abs($x - round($x));
return $x < $epsilon;
};
and you might also take a look at some arbitrary precision library, e.g. the bcmath extension where you can set "the scale of precision".
You can do it using ((int) $var == $var)
$var = 9;
echo ((int) $var == $var) ? 'true' : 'false';
//Will print true;
$var = 9.6;
echo ((int) $var == $var) ? 'true' : 'false';
//Will print false;
Basically you check if the int value of $var equal to $var
round() will return a float. This is because you can set the number of decimals.
You could use a regex:
if(preg_match('~^[0-9]+$~', $calc))
PHP will convert $calc automatically into a string when passing it to preg_match().
You can use number_format() to convert number into correct format and then work like this
$count = (float)(44.28);
$multiple = (float)(0.36);
$calc = $count / $multiple;
//$calc = 44.28 / 0.36 = 123
$calc = number_format($calc, 2, '.', '');
if(($calc) == round($calc))
die("is integer");
else
die("is not integer");
Demo
Ok I guess I'am pretty late to the party but this is a alternative using fmod() which is a modulo operation. I simply store the fraction after the calculation of 2 variables and check if they are > 0 which would imply it is a float.
<?php
class booHoo{
public function __construct($numberUno, $numberDos) {
$this->numberUno= $numberUno;
$this->numberDos= $numberDos;
}
public function compare() {
$fraction = fmod($this->numberUno, $this->numberDos);
if($fraction > 0) {
echo 'is floating point';
} else {
echo 'is Integer';
}
}
}
$check= new booHoo(5, 0.26);
$check->compare();
Eval here
Edit: Reminder Fmod will use a division to compare numbers the whole documentation can be found here
if (empty($calc - (int)$calc))
{
return true; // is int
}else{
return false; // is no int
}
Try this:
//$calc = 123;
$calc = 123.110;
if(ceil($calc) == $calc)
{
die("is integer");
}
else
{
die("is float");
}
you may use the is_int() function at the place of round() function.
if(is_int($calc)) {
die('is integer');
} else {
die('is float);
}
I think it would help you
A more unorthodox way of checking if a float is also an integer:
// ctype returns bool from a string and that is why use strval
$result = ctype_digit(strval($float));

Where to place Arrays and else issue

I'm pretty new to PHP, especially object oriented php, and I'm working on some simple code, and I'm not quite sure what's wrong with what I've written so far. I'm sure it's something simple but I've beat my head against this wall for a little bit, figured I'd ask here.
class primes
{
$TestValues = array(0, 1, 2, 3, 4);
function IsPrime($number)
{
//if number is a number, perform the rest of the tests, else, return -1 (error)
if(is_numeric($number))
{
//if number is less than 0, return -1 (error)
if($number < 0)
return -1;
//if number is 0, then return 0 (false, not prime)
if($number == 0)
return 0;
//if number is greater than 1024, return -1 (error)
if($number > 1024)
return -1;
//if number is 1, return 0 (false, not prime)
if($number == 1)
return 0;
//if number is 2, return 1 (true, is prime)
if($number == 2)
return 1;
//if number mod 2 is 0, then it is even, and no even number is prime except 2, which is handled above. so return 0 (false, not prime)
if($number % 2 == 0)
return 0;
//if number has passed all previous tests, mod it by all odd numbers from 3 to its square root rounded up.
for($i = 3; $i <= ceil(sqrt($number)); $i = $i +2)
{
//if any numbers mod 3 to its square root equal 0, return 0, (false, not prime)
if($number % $i == 0)
return 0;
}
//if the number has passed all above requirements, then it is a prime number below 1024.
return 1;
else
{
return -1;
}
}
}
function TestIsPrime()
{
foreach($TestValues as $value)
IsPrime($value);
if(IsPrime() == 0)
echo($value . "=> Is not Prime");
elseif(IsPrime() == 1)
echo($value . "=> Is Prime");
elseif(IsPrime() == -1)
echo($value . "=> Is an Error");
}
function main()
{
TestIsPrime();
}
}
main();
I'm getting an error saying I don't place my array where it is currently. I'm not quite sure how the structure of php code is supposed to work with a class, so I wasn't sure where to put the $TestValues array, so I tried a few places, and none would be accepted. Also, I'm getting an error on the else statement connected to the first if(is_numeric($number)), but I couldn't be sure that the error wasn't caused by another small error I was getting. The last error is that I'm not sure where in this single page of code to call the functions inside the class. Any help would be appreciated. Once again, I'm new to doing anything useful in php, but I'm liking it so far. Thanks,
Your code was missing several braces, also you your $TestValues is part of the class, not a global variable.
I fixed the code, however you have to check the math and read the oop tutorial on php's site.
<?php
class Primes {
public $TestValues = array(0, 1, 2, 3, 4);
function IsPrime($number) {
//if number is a number, perform the rest of the tests, else, return -1 (error)
if(is_numeric($number)) {
if($number < 0 || $number > 1024)
return -1;
if($number === 0 || $number === 1 || $number % 2 === 0)
return 0;
//if number has passed all previous tests, mod it by all odd numbers from 3 to its square root rounded up.
for($i = 3; $i <= ceil(sqrt($number)); $i = $i + 2) {
//if any numbers mod 3 to its square root equal 0, return 0, (false, not prime)
if($number % $i == 0)
return 0;
}
//if the number has passed all above requirements, then it is a prime number below 1024.
return 1;
} else {
return -1;
}
}
function test() {
foreach($this->TestValues as $value) {
$t = $this->IsPrime($value);
if($t === 0) {
echo($value . "=> Is not Prime");
} elseif($t === 1) {
echo($value . "=> Is Prime");
} elseif(IsPrime() == -1) {
echo($value . "=> Is an Error");
}
echo "\n";
}
}
}
function main() {
$prime = new Primes();
$prime->test();
}
main();
You have some syntax errors in your code. I made some modification to your code now it is working :
<?php
// Check the number to be prime or not
function IsPrime($number)
{
// If the variable is not numeric, negative or greater than 1024, exit
if (!is_numeric($number) || $number < 0 || $number > 1024)
{
return -1;
}
// Perform the tests
switch($number)
{
//if number is 0 or 1, then return 0 (false, not prime)
case 0 :
case 1 :
return 0;
break;
//if number is 2, return 1 (true, is prime)
case 2 :
return 1;
break;
}
//if number mod 2 is 0, then it is even, and no even number is prime except 2, return 0 (false, not prime)
if($number % 2 == 0)
{
return 0;
}
//if number has passed all previous tests, mod it by all odd numbers from 3 to its square root rounded up.
for($i = 3; $i <= ceil(sqrt($number)); $i = $i +2)
{
if($number % $i == 0)
{
return 0;
}
}
//if the number has passed all above requirements, then it is a prime number below 1024.
return 1;
} // End of isprime function
// create an array of numbers
$testvalues = range(-2, 100);
foreach($testvalues as $value)
{
switch(isprime($value))
{
case 0 :
echo("<p style='color:gainsboro;'>" . $value . "=> Is not Prime</p>");
break;
case 1 :
echo("<p style='color:green;'>" . $value . "=> Is Prime</p>");
break;
case -1 :
echo("<p style='color:red;'>" . $value . "=> Is an Error</p>");
break;
}
}
?>
Notes :
I think you don't need a class here. It is a simple program and using
classes will make it a bit complex and php is known for its
simplicity. So keep it simple.
In some cases switch is better and more readable than if, so use it if
possible http://php.net/manual/en/control-structures.switch.php
Every language has it preferred syntax. In php it is common not to
use capitals in naming variable (except for classes) unlike other
languages
there is no main() in php
Hope this helps, excuse my english and correct me if I am wrong
The reason why u getting error for else statement is because of the closing braces } of your if statement, notice that you have a closing brace after your else condition,instead of doing that, you have to close if statement first then do else statement which in your case else means if is not numeric then do sth, also you have so many if statements which looks a little bit redundant. what you could do is to put them in same condition like if($number ==0 || $number == 2 || $number % 2 ==0 ) return 0 elseif // do sth
The reason why you can't get $Testvalues is that you need to pass the array to your function then you can use it, where did u call your TestIsPrime function? when you call it, do sth like
TestIsPrime($TestValues);
btw, it's better not to use Capital letter for variable...

round number in php

Hello how do I round the following to two decimal places .
echo
"<div class='quote-results-result'>ex VAT £" .
((($_POST['qtylitres'] * $price ['Price']) + $fuelmargin['margin']) / 1.2) .
"</div>"
I need to round the price bit of a php novice.
Use number_format function like this:
$number = 1234.56789
$new_number = number_format($number, 2, '.', '');
echo $new_number;
Output: 1234.57
round($VARIABLE_NAME,2); //This rounds off the variable to 2 decimal places
Use round function from php manuals
echo round(3.4); // 3
echo round(3.5); // 4
echo round(3.6); // 4
echo round(3.6, 0); // 4
echo round(1.95583, 2); // 1.96
echo round(1241757, -3); // 1242000
echo round(5.045, 2); // 5.05
echo round(5.055, 2); // 5.06
function roundoff($number,$format)
{
if($number != '') {
$newNumber=$this->exp_to_dec($number);
$num = explode('.',$newNumber);
//pr($num);
if(isset($num[1]) && $num[1] != 0) {
$dec = substr($num[1],0,$format);
} else {
$dec = '00';
}
} else {
$num[0] = 0;
$dec = '00';
}
return $num[0].'.'.$dec;
}
function exp_to_dec($float_str)
// formats a floating point number string in decimal notation, supports signed floats, also supports non-standard formatting e.g. 0.2e+2 for 20
{
// make sure its a standard php float string (i.e. change 0.2e+2 to 20)
// php will automatically format floats decimally if they are within a certain range
$float_str = ( string ) (( float ) ($float_str));
// if there is an E in the float string
if (($pos = strpos ( strtolower ( $float_str ), 'e' )) !== false) {
// get either side of the E, e.g. 1.6E+6 => exp E+6, num 1.6
$exp = substr ( $float_str, $pos + 1 );
$num = substr ( $float_str, 0, $pos );
// strip off num sign, if there is one, and leave it off if its + (not required)
if ((($num_sign = $num [0]) === '+') || ($num_sign === '-'))
$num = substr ( $num, 1 );
else
$num_sign = '';
if ($num_sign === '+')
$num_sign = '';
// strip off exponential sign ('+' or '-' as in 'E+6') if there is one, otherwise throw error, e.g. E+6 => '+'
if ((($exp_sign = $exp [0]) === '+') || ($exp_sign === '-'))
$exp = substr ( $exp, 1 );
else
trigger_error ( "Could not convert exponential notation to decimal notation: invalid float string '$float_str'", E_USER_ERROR );
// get the number of decimal places to the right of the decimal point (or 0 if there is no dec point), e.g., 1.6 => 1
$right_dec_places = (($dec_pos = strpos ( $num, '.' )) === false) ? 0 : strlen ( substr ( $num, $dec_pos + 1 ) );
// get the number of decimal places to the left of the decimal point (or the length of the entire num if there is no dec point), e.g. 1.6 => 1
$left_dec_places = ($dec_pos === false) ? strlen ( $num ) : strlen ( substr ( $num, 0, $dec_pos ) );
// work out number of zeros from exp, exp sign and dec places, e.g. exp 6, exp sign +, dec places 1 => num zeros 5
if ($exp_sign === '+')
$num_zeros = $exp - $right_dec_places;
else
$num_zeros = $exp - $left_dec_places;
// build a string with $num_zeros zeros, e.g. '0' 5 times => '00000'
$zeros = str_pad ( '', $num_zeros, '0' );
// strip decimal from num, e.g. 1.6 => 16
if ($dec_pos !== false)
$num = str_replace ( '.', '', $num );
// if positive exponent, return like 1600000
if ($exp_sign === '+')
return $num_sign . $num . $zeros;
// if negative exponent, return like 0.0000016
else
return $num_sign . '0.' . $zeros . $num;
} // otherwise, assume already in decimal notation and return
else
return $float_str;
}

IMEI validation function

Does anybody know a PHP function for IMEI validation?
Short solution
You can use this (witchcraft!) solution, and simply check the string length:
function is_luhn($n) {
$str = '';
foreach (str_split(strrev((string) $n)) as $i => $d) {
$str .= $i %2 !== 0 ? $d * 2 : $d;
}
return array_sum(str_split($str)) % 10 === 0;
}
function is_imei($n){
return is_luhn($n) && strlen($n) == 15;
}
Detailed solution
Here's my original function that explains each step:
function is_imei($imei){
// Should be 15 digits
if(strlen($imei) != 15 || !ctype_digit($imei))
return false;
// Get digits
$digits = str_split($imei);
// Remove last digit, and store it
$imei_last = array_pop($digits);
// Create log
$log = array();
// Loop through digits
foreach($digits as $key => $n){
// If key is odd, then count is even
if($key & 1){
// Get double digits
$double = str_split($n * 2);
// Sum double digits
$n = array_sum($double);
}
// Append log
$log[] = $n;
}
// Sum log & multiply by 9
$sum = array_sum($log) * 9;
// Compare the last digit with $imei_last
return substr($sum, -1) == $imei_last;
}
Maybe can help you :
This IMEI number is something like this: ABCDEF-GH-IJKLMNO-X (without “-” characters)
For example: 350077523237513
In our example ABCDEF-GH-IJKLMNO-X:
AB is Reporting Body Identifier such as 35 = “British Approvals Board of Telecommunications (BABT)”
ABCDEF is Type Approval Code
GH is Final Assembly Code
IJKLMNO is Serial Number
X is Check Digit
Also this can help you : http://en.wikipedia.org/wiki/IMEI#Check_digit_computation
If i don't misunderstood, IMEI numbers using Luhn algorithm . So you can google this :) Or you can search IMEI algorithm
Maybe your good with the imei validator in the comments here:
http://www.php.net/manual/en/function.ctype-digit.php#77718
But I haven't tested it
Check this solution
<?php
function validate_imei($imei)
{
if (!preg_match('/^[0-9]{15}$/', $imei)) return false;
$sum = 0;
for ($i = 0; $i < 14; $i++)
{
$num = $imei[$i];
if (($i % 2) != 0)
{
$num = $imei[$i] * 2;
if ($num > 9)
{
$num = (string) $num;
$num = $num[0] + $num[1];
}
}
$sum += $num;
}
if ((($sum + $imei[14]) % 10) != 0) return false;
return true;
}
$imei = '868932036356090';
var_dump(validate_imei($imei));
?>
IMEI validation uses Luhn check algorithm. I found a link to a page where you can validate your IMEI. Furthermore, at the bottom of this page is a piece of code written in JavaScript to show how to calculate the 15th digit of IMEI and to valid IMEI. I might give you some ideas. You can check it out here http://imei.sms.eu.sk/index.html
Here is a jQuery solution which may be of use: https://github.com/madeinstefano/imei-validator
good fun from kasperhartwich
function validateImei($imei, $use_checksum = true) {
if (is_string($imei)) {
if (ereg('^[0-9]{15}$', $imei)) {
if (!$use_checksum) return true;
for ($i = 0, $sum = 0; $i < 14; $i++) {
$tmp = $imei[$i] * (($i%2) + 1 );
$sum += ($tmp%10) + intval($tmp/10);
}
return (((10 - ($sum%10)) %10) == $imei[14]);
}
}
return false;
}

Categories