Discrepancy between BASIC INT and PHP int, how to resolve? - php

I've been re-writing a BASIC program to PHP. I've run across a problem, let me explain:
In the BASIC code I have the following statement with values:
LSLATVER=1590
PITCHVER=50
NRSLATHOR=INT(LSLATVER/PITCHVER-.8)
// output: 30
In PHP the code I have two examples like this:
$length_vertical_slat = 1590;
$vertical_pitch = 50;
echo $number_of_horizontal_slats = (int) ($length_vertical_slat / $vertical_pitch - .8);
// output: 31
echo $number_of_horizontal_slats = (int) ($length_vertical_slat / ($vertical_pitch - .8));
// output: 32
Why is there such a huge difference between the 3 examples? I need the PHP to output a value of 30 in this example but I do not see how to go about it. Please help ty!

The BASIC is using integer division, as well as reducing the final result to an int, so you'll want to mimic this in PHP (PHP converts to float by default, rather than reducing to an int).
This means that at BOTH stages (the division, and the subtraction) you'll want to reduce the value to an int. The PHP docs recommend doing this by casting to an int, like you did in your examples:
$length_vertical_slat = 1590;
$vertical_pitch = 50;
// outputs 30
echo $number_of_horizontal_slats = (int)((int)($length_vertical_slat / $vertical_pitch) - .8);
From the PHP docs:
There is no integer division operator in PHP. 1/2 yields the float
0.5. The value can be casted to an integer to round it downwards, [...]

Related

PHP interprets numbers as floats even when they're less than INT_MAX

PHP documentation here states that:
If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.
But what about an operation which results in a number less than PHP_INT_MAX ?
See this code snippet as an example:
$max_int = 2**31-1 ; // 2147483647
var_dump(PHP_INT_MAX === $max_int); // false
As you can see, even when an operation results in a valid int value PHP seems to cast the result into float
var_dump(PHP_INT_MAX === (int) $max_int) // true
My questions:
Does PHP interpreter cast the result into float before making any calculations?
Shouldn't PHP calculate the result and then sets the type accordingly? (Makes sense right?)
Edit:
PHP version: 7.2.1 32-bit
OS: Windows: 10 x64
I'm using XAMPP
When calculating $max_int = 2**31-1 the engine does this in steps:
$tmp = 2**31;
$max_int = $tmp-1
Here $tmp is bigger than maximum integer value and converted to a floatng point number. In consequence there is an float subtraction, resulting in a float. Since it had been float it has to stay float.

php only show decimal place if have fraction

I set int data type in mysql database but it not showing decimal place like 10.20
Then I set decimal(10,5) it show five decimal place with all number thought it not necessary like 10.00000.
I want to show decimal places only if have fraction
like 10.25455 = 10.25455 and 10 = 10 but it showing 10 = 10.00000
how to solve this
You can use PHP round function.
http://php.net/manual/en/function.round.php
PHP Code:
<?php
echo round(10.25455, 5); // outputs: 10.25455
echo '<br/>';
echo round(10.00000, 5); // outputs: 10
Just add 0!
echo 10.25455 + 0;
echo 10.00000 + 0;
Output:
10.25455
10
Use decimal as a field type. Then in PHP use round(); function.
There is no datatype in mysql that supports your requirement. In fact, that is not how computers work. A number is either an int or a float.
You might want to use varchar instead, and cast to the right data type in php, but it might cause performance overhead. It is indeed a weird data type requirement. If you must go this route, consider adding an extra column for flagging data type.
echo floatval($value);
will do the trick.

PHP 7 intdiv() vx floor or custom type cast

I am looking PHP 7 new Additions in order to improve my skills, i want to know what exactly the difference between the intdiv() vs floor() or custom type cast
for example
echo (int) (8/3); // 2
echo floor((8/3)); // 2
echo intdiv((8/3)); // 2
what exactly the reason for this function to add in newer version of PHP.
(int) casts the value to int whereas floor() keeps a float as a float. You used positive numbers in your example, but the difference is in negative numbers.
intdivwas designed to keep int after division of 2 ints.
echo (int) (-8/3); // -2
echo floor(-8/3); // -3
echo intdiv(-8,3); //-2
There is a different in how they behave in terms of rounding.
divint() is more intelligent, it always knows if it supposes to round up or down.
floor()
With floor(), you will always round the value lover so:
3.33333 becomes 3
-3.33333 becomes -4
Which is often not what you intend.
divint()
divint will round to the closest number:
3.33333 becomes 3
-3.33333 becomes -3
Casting to (int)
Casting float/double to a int will perform similary like divint. So you can use:
(int)(10/3) returns 3
(int)(-10/3) returns -3
In general all these three you mentioned works similar as of your example but intdiv() will give you more accurate result while working extremely large set of numbers
here is example you can see.
echo PHP_INT_MAX; // 9223372036854775807
echo (int)(PHP_INT_MAX/2); // 4611686018427387904
// here you can look the ending number
echo floor(PHP_INT_MAX/2); // 4.6116860184274E+18
// here you can see floor will return scientific notation for larger numbers
echo intdiv(PHP_INT_MAX,2); // 4611686018427387903
// you can compare the result return by (int) cast
intdiv() always give you positive number or in other word intdiv() let you know how many times you can divide evenly
Another example developer always use Modulus Operator in order to get remainder but intdiv() will always return you positive numbers and let you know how many times you can divide evenly.
echo (5 % 2) // 1
echo intdiv(5, 2) // 2
Hope this good enough to understand the difference among all 3 of them..

Float to int error

Yesterday I was helping some one and got a weird error which I could not explain to him how it worked.
The code (tested on 3 machines (PHP 5.3 and PHP 5.4))
// (float)65.35
$percentage = round(65.351, 2);
// (float) 6535
$total = $percentage * 100;
// (int) 6534
$int = (int) $total;
What is suspected was that the int value would be 6535 but it ended up being 6534.
Could some one explain what is going on?
You don't actually have 65.35 after the first operation.
>>> '%.20f' % (65.351 - 0.001,)
'65.34999999999999431566'
Either start with an integral value scaled appropriately in the first place, don't attempt to convert the value to an integer, or add a small value before taking the integer value.
This has to do with how floating point (read the warning in this link!) values are stored in memory. Indeed after the first operation you don't have an exact decimal value, but a rounded value. Probably 65.34999999 or so. (The value is stored as a list of bits (0/1))
This is why when talking about money, developers don't store dollars/euros but rather the amount of cents. This way they avoid working with floats that are less precise for decimals, but rather work with integers, that are precise.
Use round instead of int
round($total)
$r=$explode('.',$total);
debug($r);

Converting two integers into a long in PHP

I've got two integers and I need to convert them into a long. I'm totally lost on how to do this. The two integers that I need to convert are:
INT 1: 60850985
INT 2: 59150141
I need a method that converts two integers into a long. If you can post one, that'd be great.
When I say converting to a long, I'm wondering how you would do the equivalent of (long) from java in PHP
Let me be completely clear here:
I'm receiving two ints from the client, then I need to convert them to a long, then the single long is to be used again as a single int.
In essence, I need to take two ints and convert them into a single int. An example of how this is done in java would be:
long $intA = (long) readInt();
long $intB = (long) readInt();
return ($intA << 32) + $intB;
PHP stores numbers as integers or floats, where the size of the integer is platform dependent (but usally 32 bit, signed). If you need to represent a larger number you should use the BC Math functions.
Using BCM adding two numbers is like:
$a = '60850985';
$b = '59150141';
echo bcadd($a, $b);
or multiplying:
$a = '60850985';
$b = '59150141';
echo bcmul($a, $b);
EDIT:
If you want to get, how it should look as a 64-bit signed integer in 1-complement (if there is an overflow), then you have to do some manual conversion to cast the value inside the -2^63 .. 2^63-1 range:
For nonnegative values you can for example first cast it to 0 .. 2^64-1:
$long = bcmod($value, bcpow('2','64'));
Then if it's larger than 2^63-1 then subtract 2^63 from it, and then subtract this value from -2^63.
For negative values, first add 2^64, until the value is positive, then do the above steps.
But the above steps are only needed if you want to check how the string number looks if there was an overflow. Usually you don't need this, and probably you don't even need to use BCM as your numbers will easily fit inside PHP's signed 32-bit integer datatype (for which no casting is needed, conversion is automatical):
$a = '123'; // $a is a string
echo $a + 1; // will write 124, $a gets converted into int
You can force conversion if you want though:
$a = $a+0;
or
$a = (int)$a;
EDIT 2:
You can still use BCM functions to do the math:
$long = bcadd($low, bcmul($high, bcpow('2','32')))
// this essentially means:
// $long = $low + $high * 2^32
// which is
// $long = $low + $high << 32
Then, if the result is larger than 2^63-1 you can do some additional BCM calculations, described above to convert the unsigned integer into a signed one.
I used regular addition:
$int1 = 60850985;
$int2 = 59150141;
$result = $int1 + $int2;//120001126
Here's a quote from the PHP manual:
The size of an integer is platform-dependent, although a maximum value
of about two billion is the usual value (that's 32 bits signed).
64-bit platforms usually have a maximum value of about 9E18. PHP does
not support unsigned integers. Integer size can be determined using
the constant PHP_INT_SIZE, and maximum value using the constant
PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.
If you want to deal with large numbers use GMP ( http://www.php.net/manual/en/book.gmp.php ) or BCMath ( http://www.php.net/manual/en/book.bc.php ).
To elaborate on what AgentConundrum said, there isn't a need to cast an integer to a long in PHP. PHP is a dynamic language which means that generally, for operations on fundamental types, there is no need for casting (unless it is for some explicit purpose - i.e. a float to an integer), as PHP handles it for you.

Categories