How to use a 32bit integer on a 64bit installation of PHP?
Asked Answered
S

4

5

I run into a problem on my code when moved to production because the production server is 32bit while my development machine is 64bit (I'm running Kubuntu 12.04 64bit). My question is. Is it possible to force an int to be 32bit without installing the 23bit version of PHP? Either that or a library that allow me to chose the max int value

Skindeep answered 21/3, 2013 at 20:27 Comment(4)
nope. PHP doesn't provide control over variables that way. you can't make a var be a "short" or an "int" or "unsigned". There's just integers, strings, objects, arrays. No reason you can't install a 32bit version of PHP, however. it possible to have multiple independent php installs.Thundershower
What kind of operations are you performing in your PHP code that might need an int to be of 32 bits ?Flyback
You could just limit the int (with a setter function) to not surpass the 32-bit integer numeral limit (2,147,483,647). So you can throw an exception if you set the general integer to be higher than that. This is not foolproof off course. Also it will likely not gain you memory, as PHP will still reserve all space for the 64-bit integer. The final thing you could do is make a class that represents a 32-bit integer with chained chars, but this will likely not gain you anything much than just using 64-bit integers.Women
A simple (int) cast. I fixed the bug, but forcing the 32bit would help o the unit tests. Yeah I was hoping there was a way to not have to have a separate install. Too bad =/Skindeep
C
10

Integers are the size of pointers on that platform. (32-bit PHP --> 32-bit integers. 64-bit PHP --> 64-bit integers).

Note that when integer operations overflow, the variables become floats. The PHP documentation explains all of this well.

I'm not sure what you're doing in your code that would cause you to care what size the integer is though. If you only care about 32-bits of a value, however, you can always mask off the low 32 bits:

$val = $something & 0xFFFFFFFF;
Cannonball answered 21/3, 2013 at 20:34 Comment(2)
$val = $something & 0xFFFFFFFF; this line made my day thanks!Emulous
One case is in for instance calculating a CRC32, without using the build in CRC32 that is, as in my case I need to do it one byte at a time. Here you are multiplying fairly large integers, and you want them to behave like signed 32-bit integers, even on a 64 bit system.Marilynnmarimba
K
3
$r = $r & 0xFFFFFFFF;
if ($r & 0x80000000)
{
    $r = $r & ~0x80000000;
    $r = -2147483648 + $r;
}
Kalliekallista answered 9/3, 2019 at 15:51 Comment(3)
Please add some explanation to your code - how does it answer the given question?Strappado
Seems like this solution also simulates int overflow?Treasurehouse
How does the $r = $r & ~0x80000000; part work? What's the point of negating the bits with ~ and then doing $r = -2147483648 + $r;?Boondocks
P
1
$r = $r & 0xFFFFFFFF;
if ($r & 0x80000000)
{
    $r = $r & ~0x80000000;
    $r = -2147483648 + $r;
}

Trying to give an explanation for who requested it.

Take your $r big number variable (let's say spread on 64 bits) and let only the 32 most right bits to pass.

$r = $r & 0xFFFFFFFF; //aka 0x00000000FFFFFFFF

Now 64bits $r variable has 32 zeros and your 32 bits. Note that conventionally the most left bit is the sign, in both 64 and 32 bits representation: plus (0) or minus (1), so 64bits $r is now considered positive by PHP.

if ($r & 0x80000000) {

"32 zeros, your 32 bits" ANDed with "32 zeros, 1 and 31 zeros": if this gives true, meaning there is at least (at most) one 1, which again means: "in the 32bit world, this is a negative number", in this case then we need to also tell PHP that this is a negative number, because most left bit of the 64bits $r variable is still 0 and PHP still thinks is a positive number.

So, let's tell PHP this is actually a negative number and rebase the number. First step, set to zero just the most left of your 32 bits to force the positiveness of your 32bits.

$r = $r & ~0x80000000;

~0x80000000 indeed can be rewritten as 0xFFFFFFFF7FFFFFFF: 32 ones, 1 zero, 31 ones.

Now you have a positive 32bit number representation inside a 64bit variable and it is complementary of it's related 32bit negative representation: e.g. if you had 64 ones in the very beginning (-1 in decimal), at this point $r is 32 zeros, 1 zero you just set, 31 ones (2147483647 in decimal).

You should now see the point:

$r = -2147483648 + $r;

Minimum representable 32bit number + our complementary positive number.

At this point, $r variable is still a 64bit variable, but it now correctly represents the negativiness of the 32 most right bits you chose in the beginning.

The whole problem is that in 64bit PHP, if you extract the most right 32 bits and you fill another 64bits variable with, the value is still positive because the most left of the 64bits is 0. What we wanted to achieve instead: making the 64bits variable negative, if the extracted 32bits represent a negative number; a 64bits variable positive, if the extracted 32bits represent a positive number.

Popularly answered 12/8, 2021 at 14:48 Comment(0)
R
-2

Just populate the thirty-second bit into bits from 33 to 64

$r = $r & 0xFFFFFFFF;
if ($r & 0x80000000)
{
    $r = -0x100000000 | $r; // is (0xFFFFFFFF << 32) | $r or (-1 << 32) | $r
}
Remainder answered 30/8 at 16:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.