5

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.

Sahil Mittal
  • 20,697
  • 12
  • 65
  • 90
Joachim Vanthuyne
  • 355
  • 1
  • 4
  • 14
  • 1
    try `is_int()` instead of your code – krishna Mar 24 '14 at 10:59
  • You could also use Modolo '%' if you are hipster enough. – cptnk Mar 24 '14 at 11:00
  • Why not use `is_float`? – putvande Mar 24 '14 at 11:00
  • http://stackoverflow.com/questions/3280892/difference-between-float-and-double-in-php – Rufinus Mar 24 '14 at 11:01
  • Ugly but working too: `(string)(int)$value === (string)$value` – ToBe Mar 24 '14 at 11:02
  • float calculations aren't precise that's why you are facing issues, try `echo (int)$calc-$calc` you'll see that the output isn't `0`, I think you'll have use @ToBe way – CodeBird Mar 24 '14 at 11:12
  • 1
    why do you need to know in the first place? what do you want todo? – Rufinus Mar 24 '14 at 11:30
  • If the calculation is integer I don't need to do anything. If the calculation is float(has decimals) I need to ceil the value. – Joachim Vanthuyne Mar 24 '14 at 11:33
  • 1
    ceil the value without knowing :D if it is an int it won't change anything if it is a float it will ceil... more efficient than using if's – CodeBird Mar 24 '14 at 11:34
  • @CodeBird ceil will not work here. It is converting 123 into 124. check [here](http://3v4l.org/0PuoK) – krishna Mar 24 '14 at 11:37
  • If you need better precision (float is only a rough estimation) you can use bc math functions. There are methods for division and for rounding. Check top comment on the page for bcscale for good samples. – ToBe Mar 24 '14 at 11:51
  • ceiling an integer in this case 123 will make it into 124 and that's not correct. – Joachim Vanthuyne Mar 24 '14 at 11:53
  • Say what? `ceil(123) == 123` http://3v4l.org/mFLo1 – deceze Mar 24 '14 at 13:25
  • In your case it appears that ceil(123) is 124 but actually you're not passing 123 to the function but a value that is a tat bigger. Just take a look at the value via `printf("v=%.18e\nl=%.18e", $calc, 123.0);`, you will most likely see that the value of calc is greater than `1.230000000000000000e+2` – VolkerK Mar 24 '14 at 13:51

10 Answers10

9

Try-

if ((string)(int) $calc === (string)$calc) {
  //it is an integer
}else{
  //it is a float
}

Demo

Sahil Mittal
  • 20,697
  • 12
  • 65
  • 90
  • This will not work, as it would return true even for `1 == 1.00` . (Or I misunderstood the question) – hek2mgl Mar 24 '14 at 11:05
  • 2
    @Rufinus : don't make it === because $calc is still a float/double and === also tests the type. – VolkerK Mar 24 '14 at 11:07
  • 1
    this won't work becuse of float calculation precision, check here: https://eval.in/125555 – CodeBird Mar 24 '14 at 11:15
  • @VolkerK `$foo = intval(1); echo ((int) $foo === $foo) ? 'int' : 'something else'; $bar = floatval(1.23); echo ((int) $bar === $bar) ? 'int' : 'something else';` will print "int" and "something else" – Rufinus Mar 24 '14 at 11:28
  • @Rufinus : yes, and that's apparently not what the OP wants. `$foo=1.00;` should yield `int` but in case of === says `something else`. – VolkerK Mar 24 '14 at 11:30
  • @VolkerK mhhh if thats the case you are right... but then im guessing its just for output formating, and op never heard of number_format :-) why else should he have to know if he has decimals when he dont care he can ceil/floor, round, intval... whatever... – Rufinus Mar 24 '14 at 11:34
  • This is not for formatting, if calculation is integer I don't need to do something extra. But if the calc is float I need to ceil the calculation. – Joachim Vanthuyne Mar 24 '14 at 12:07
  • "But if the calc is float I need to ceil the calculation" - that sounds to me like you don't have to test anything but just typecast it to (int) in any case? – VolkerK Mar 24 '14 at 12:11
  • No if I typecast 12.3 to int I have 12, and I need it to be 13. And if I do ceil in any case an integer like 123 is typecasted to 124 which is also not correct. – Joachim Vanthuyne Mar 24 '14 at 12:33
  • 1
    i dont see your problem `echo ceil(12); echo ceil(12.0); echo ceil(12.1); ` output ist 12, 12, 13. (PHP 5.5.3) – Rufinus Mar 24 '14 at 12:47
3

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".

VolkerK
  • 95,432
  • 20
  • 163
  • 226
1

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().

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • `is_int()` or `is_float()` is better for this purpose – krishna Mar 24 '14 at 11:02
  • @krishna is_int() will not work as the result of `round()` is a float. You are wrong. – hek2mgl Mar 24 '14 at 11:03
  • @hek2mgl if the number is float then if condition fails and goes to else part(i think this is what OP wants). so there will not be any problem in using it. check [here](http://3v4l.org/sINCl) – krishna Mar 24 '14 at 11:06
  • I understood the question in a way the he want's to make sure that the number has no decimals regardless of the data type. I'm not sure. Maybe I misunderstood that. – hek2mgl Mar 24 '14 at 11:08
  • Yea i think what you understood was correct. What i am trying to say is using `preg_` function for this small process is not good.we have other functions which can finish this work in less time. – krishna Mar 24 '14 at 11:16
  • @hek2mgl I think Sahil Mittal answer will be more faster than `preg_`.But need to be tested in all cases. Also you have error in your code. You have missed out `/` in `preg_`. Also Your solution is not working. check [here](http://3v4l.org/lYsLD) – krishna Mar 24 '14 at 11:51
  • @krishna Sahil's solution will be faster and is the best solution. That's out of question and I'm with you. I just asked because you told "other functions", and I don't have a PHP core function for this in mind. Thought I might missing something. Thanks for the tipp with the missing delimiter in my regex! :) – hek2mgl Mar 24 '14 at 12:03
  • i thought of using `is_int()`. But it failed. we can use number_format() as posted by me. but i think both(my solution and yours) will take nearly same time. Also i am such an idiot that i didnt even notice that you are using `~` in case of `/`. – krishna Mar 24 '14 at 12:09
  • I personally dont like the Idea of using a string comparission for a mathematical problem. It just does not feel natural nor is it easy for other's who may work with/on your code to understand your toughtprocess or what the heck is happening right there. I upvoted this non the less because it does work exactly like op wanted. I still would not use it though. – cptnk Mar 24 '14 at 13:52
  • I would also use Sahil's answer in this case. – hek2mgl Mar 24 '14 at 14:06
  • Kudos! for coming up with a preg_match though. It does look pretty cool for a 1 liner :D – cptnk Mar 24 '14 at 14:09
1

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

darkheir
  • 8,844
  • 6
  • 45
  • 66
1

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

krishna
  • 4,069
  • 2
  • 29
  • 56
1

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

cptnk
  • 2,430
  • 18
  • 29
  • I did test this for about 2 min's I might miss something. If I do please tell. – cptnk Mar 24 '14 at 12:06
  • 1
    I'm not sure if this is what OP wants, but however, thanks for showing `fmod()` I didn't seen it before. – hek2mgl Mar 24 '14 at 14:35
0
if (empty($calc - (int)$calc))
{
    return true; // is int
}else{
    return false; // is no int
}
Dylan Westra
  • 611
  • 1
  • 5
  • 10
0

Try this:

//$calc = 123;
$calc = 123.110;
if(ceil($calc) == $calc)
{
    die("is integer");
}
else
{
    die("is float");
}
Nikunj Kabariya
  • 840
  • 5
  • 14
0

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

Rahul Goyal
  • 203
  • 1
  • 8
0

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));
Elzo Valugi
  • 27,240
  • 15
  • 95
  • 114