I pulled this result from here:
And interestingly, the result of var_dump((int)(PHP_INT_MAX + 1)) will be displayed as a negative number (in the case of this specific example, it will display int(-9223372036854775808)). Again, the key here is for the candidate to know that the value will be displayed as a negative number.
Is the int negative because adding 1 will overflow the integer bits and change the bit representing the sign of the int? What's the reason?
#kainaw is right.
This is called "buffer overflow". PHP handled it in the best way possible.
If PHP didn't make that integer positive, there would be an extra "bit" floating around in the RAM (probably causing a 502 error, but it could be much worse)
Related
The operation 1539 | 0xfffff800 returns -509 in JavaScript and Python 2.7.
In PHP I get 4294966787.
Does anybody know why and could explain that to me. I would love to know how I get the expected result in PHP as well.
1539 | 0xfffff800 = 4294966787 (= 0xFFFFFE03)
This is perfectly right. So, PHP is right.
If you would like to have both positive and negative integers, you need some mechanism to determine whether the number is negative. This is usually done using the 2-complement of the number. You can negate a number by just inverting all the bits of the number and then add 1 to it. In order to avoid ambiguities, you cannot use all the bits of your integer variable. You cannot use the highest bit in this case. The highest bit is reserved as a sign bit. (If you would not do so, you never know if your number is a big positive number or a negative number.)
For exammple with an 8 bit integer variable, you would be able to represent numbers from 0 to 255. If you need signed values, you can represent number from -128 (1000 000 binary) to +127 (0111 1111).
In your example, you have a 32 bit number which has its highest bit set. In Python and JavaScript, it's interpreted as negative number, as they apparently have 32 bit variables, and there, the highest bit is set. They interpret that as negative number. So, the result of your calculation is also negative.
In the PHP version you are using, the integer variable seems to be 64 bit long and only the lower 32 bits are used. The highest bit (bit 63) is not set, so PHP interprets this number as positive. Depending on what you want to achive, you may want to fill up all bits from bit 32 to bit 63 with 1s which will create a negative number...
I am trying to resolve the following problem via PHP. The aim is to generate a unique 6-character string based on an integer seed and containing a predefined range of characters. The second requirement is that the string must appear random (so if code 1 were 100000, it is not acceptable for code 2 to be 100001, and 3 100002)
The range of characters is:
Uppercase A-Z excluding: B, I, O, S and Z
0-9 excluding: 0, 1, 2, 5, 8
So that would be a total of 26 characters if I am not mistaken. My first idea would to be encoding from base 10 to base 24 starting at number 7962624. So do 7962624 + seed, and then base24 encode that number.
This gives me the characters 0-N. If I replace the resulting string in the following fashion, I then meet the first criteria:
B=P, I=Q, 0=R, 1=T, 2=U, 5=V, 8=W
So at this point, my codes will look something like this:
1=TRRRR, 2=TRRRT, 3=TRRRU
So my question to you gurus is: How can I make a method that behaves consistently (so the return string for a given integer is always the same) and meets the 2 requirements above? I have spent 2 full days on this now and short of dumping 700,000,000 codes into a database and retrieving them randomly I'm all out of ideas.
Stephen
You get a reasonably random looking sequence if you take your input sequence 1,2,3... and apply a linear map modulo a prime number. The number of unique codes is limited to the prime number so you should choose a large one. The resulting codes will be unique as long as you choose a multiplier that's not divisible by the prime.
Here's an example: With 6 characters you can make 266=308915776 unique strings, so a suitable prime number could be 308915753. This function therefore will generate over 300.000.000 unique codes:
function encode($num) {
$scrambled = (240049382*$num + 37043083) % 308915753;
return base_convert($scrambled, 10, 26);
}
Make sure that you run this on 64bit PHP though, otherwise the multiplication will overflow. On 32bit you'll have to use bcmath. The codes generated for the numbers 1 through 9 are:
n89a2d
hdh4jo
biopb9
5o6k2k
3eek5
k8m9aj
ee4424
8jbojf
2ojjb0
All that's left is filling in the initial 0s that are sometimes missing and replacing the letters and numbers so that none of the forbidden characters are produced.
As you can see, there's no obvious pattern, but someone with some time on their hands, enough motivation and with access to a few of this codes will be able to find out what's going on. A safer alternative is using an encryption algorithm with a small block size, such as Skip32.
I am working on this affiliate that computes numbers and adds them up then i get a number like 5.1882449992845E+25 how do i force the number to 2 decimal places so that i can have just integer.
I would like to know any php function that this with such numbers and what it means.
Use number_format php function:
number_format(5.211545645612456,2);
For more information refer http://php.net/manual/en/function.number-format.php
The number 5.1882449992845E+25 really means 5.1882449992845 * 10^25 (see here).
Unfortunately this is massive. If you are intent on storing this as a number (i.e. if you need to apply maths to it) then you should be able to parse the string and apply the exponent. Be warned however the max int size in PHP is usually 2 Billion (although this is platform independent). It's unlikely you'll be able to store this as an int. Otherwise if it is just to be used as an id or the like I would leave it as is or alternatively convert it to an int string.
I have an array of 52 different values that I can pass through a class to get a number in return.
$array = array("A","B","C","D"...);
Each value passed through the class gives a different number that can be either positive or negative.
The numbers are not equally distributed but are sorted in natural order.
E.g.
$myclass->calculate("A"); // 2.3
$myclass->calculate("B"); // 0.25
$myclass->calculate("C"); // -1.3
$myclass->calculate("D"); // -6
I want to get the last value that return a number >= 0.20 (in the example would be "B").
This should be done in the minimum number of "class invocation" to avoid time wasting.
I thought something like: divide $array in 2 pieces and calculate the number I get, if it is >= 20, then split the last part of $array in other 2 smaller pieces and so on. But I don't know if this would work.
How would you solve this?
Thanks in advance.
What you're describing is called a binary search, but it won't really work for this use case, because you aren't searching for a known value. Rather, you're searching for the value that is the lowest number >= 0.2 in a set where the exact value 0.2 may not exist (if it were guaranteed to exist, then you could do a binary search for 0.2, and then your letter would simply be n - 1; n != 0).
If your range is always A-Z, a simple linear search would definitely be the easiest method. The time savings on a data set of 26 elements for using a more efficient method is negligible (talking milliseconds here), compared to implementation time.
Edit: I see you actually mentioned 52 elements, not 26. My point is still the same, though. The number of elements would need to be in the tens of thousands or more for there to be any significant savings, unless you are performing this operation in a tight loop.
I have one PHP script inserting rows in a MySQL database. Each row has a field 'created_at' which is filled with the value of the PHP function microtime(true), and inserted as a double. (microtime because I need something more precise than to the second)
I have another PHP script that selects rows based on that created_at field.
When I go ahead and select like this:
SELECT * FROM `ms_voltage` WHERE created_at > 1302775523.51878
I receive a resultset with, as the first row, the row with exactly that value for created_at.
This occurs from within my PHP script and from within PhpMyAdmin when manually doing the query. But not always, not for every value. Just once and a while really.
How is this possible? I didn't ask for greater than/equals, I want strictly greater than.
Am I overlooking something type-related perhaps?
Yeah, floating point arithmetic can do that sometimes. To understand why, it's helpful to realize that just as not all numbers can be accurately represented in base 10, not all numbers can be accurately represented in base 2 either.
For example, "1/3" may be written in base 10 as 0.33333 or 0.33334. Neither is really "correct"; they're just the best we can do. A "DOUBLE" in base 10 might be 0.3333333333 or 0.3333333334, which is double the digits, yet still not "correct".
The best options are to either use a DECIMAL value, or use an INT value (and multiply your actual values by, say, 10000 or 100000 in order to get the decimal digits you care about into that int).
The DOUBLE type represent only approximate numeric data values. Try to use the DECIMAL type.
Is your column floating point? Calling microtime with true gives you a float, and that looks like a float, which will have digits after the .51878 that you don't see, so those digits make the stored value greater than the value you have in your query.
Unless you really need the float I'd convert the string result to an int, or even two columns for seconds and useconds. Then you can use > or < on known values without worrying about the imprecision of the floating point value.