-
-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why limit integer support to 2147483647? #35
Comments
I have tried setting Checking the prime versus inverse-prime with I'm not yet sure where the fault lies. I Suspect I will need to read up on |
Yeah I tried to up the number as well, but with bad collisions. Would be a awesome if you could help out on this! |
An upfront word of warning: I'm not a mathematician. So most of the concepts in this are completely foreign to me. And what I'm about to say is based on not more than a days worth of research. I found that 2^32-1 is not just a Prime, it's a Mersenne Prime. I think this is significant in producing an It seems that only certain So Having said that, I have not found the strategy used in Optimus documented anywhere. There are a lot of discussions of Knuth's Multiplicative Hashing, but none that involve an modular multiplicative inverse and mention of the Mersenne Prime. If I could find mention of this strategy then perhaps it will provide details about the |
Ahah! So I have confirmation that the strategy used in Optimus does not require primes and a Mersenne Prime as a So The example from the above link would use 1000000000 for So having Optimus use a Mersenne Prime for I have not yet written code to test this yet. I also need to determine if it may be that a it is best if |
Hmmm... so I was way off. The maths was all perfect. The problem comes back to PHPs handling of extremely large integers. With 2^32 for The following is a sample diff to demonstrate that it works if we switch to GMP when the multiplication exceeds Index: src/Optimus.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/Optimus.php (revision cec96e8f597cc331a1e0fde5af17ab6621b5aa9e)
+++ src/Optimus.php (date 1519649807000)
@@ -9,7 +9,8 @@
/**
* @var int
*/
- const MAX_INT = 2147483647;
+// const MAX_INT = 2147483647;
+ const MAX_INT = 4294967295;
/**
* @var string
@@ -98,7 +99,14 @@
return gmp_intval(gmp_mul((int) $value ^ $this->xor, $this->inverse)) & static::MAX_INT;
default:
- return (((int) $value ^ $this->xor) * $this->inverse) & static::MAX_INT;
+ $a = (int) $value ^ $this->xor;
+ $b = $a * $this->inverse;
+
+ if ($b < PHP_INT_MAX) {
+ return $b & static::MAX_INT;
+ } else {
+ return gmp_intval(gmp_mul($a, $this->inverse)) & static::MAX_INT;
+ }
}
}
So when dealing with larger I'm happy to raise a PR to allow the |
PR would be great. Would prefer to throw an exception if the user is trying to do something that is impossible, eg; |
PR #36 has been submitted. |
Hey @jenssegers, I thought I would drag the conversation about getting this to work with any sized Max Int out of the PR into this ticket.
I have been examining the maths behind this to see why it does not work, to then see what would make it work. I think the key thing for this is I will use following specific example that works for this formula and disect it. (211 * 91) & 255 The 0b100101100000001 & 0b11111111 // 1 So we can see that this works If the MAXINT was 200, it's binary representation would be I will now examine the encode/decode formula's we can also see why a base 2 number is required for
So if we encode the number 23 this is what we get. (23 * 211) & 255 // 245
(0b10111 * 0b11010011) & 0b11111111 // 0b11110101
(0b1001011110101) & 0b11111111 // 0b11110101 And if we decode it.... (245 * 91) & 255 // 23
(0b11110101 * 0b1011011) & 0b11111111 // 0b10111
(0b101011100010111) & 0b11111111 // 0b10111 (i.e. the last 8 digits of `VALUE * INVERSE`) So the true number is buried in the last 8 bits of the result of So that's the problem... and having written this I think I see a possible backwards-compatible solution. Stay tuned... |
@courtney-miles did you eventually find a solution? |
No I didn't, sorry. It was taking too much time and I had to move on. So I'm unsure if there is a solution that is compatible with Optimus. |
I have adopted Optimus assuming it would support integers up to 2^32-1.
Is there a technical reason why it is limited to 2^31-1? Is it that the method only works when the max integer is prime number?
I would be happy to submit a PR to make the range configurable. But I don't fully understand the maths to know if there's a logical problem with this.
In terms of the maths, why is a large prime preferred over a small prime?
The text was updated successfully, but these errors were encountered: