Created
October 5, 2020 13:45
-
-
Save skial/c5bd1375c617e1f5dbb99174a465a18e to your computer and use it in GitHub Desktop.
Ascii string to decimal parser, 0-9 are the only valid characters. Why? Because an itch HAD to be scratched 🤷♀️ Its not worth using and its most likely hugely unoptimized from a bitwise standpoint. Just use a regular expression!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ; | |
class StringParser { | |
public static function parseDecimal(v:String):RawInt { | |
var result:RawInt = 0; | |
var code = 0; | |
var base = 1; | |
var index = v.length; | |
var start = v.fastCodeAt(0); | |
var isMinus = -((start & 1) & ((start & 4) >> 2) & ((start & 8) >> 3) & ((start & 32) >> 5) & ((~start & 15) >> 1)); | |
var sign = ((isMinus) | (~isMinus & 1)); | |
while (index > 0) { | |
code = v.fastCodeAt(index-1); | |
/** | |
Binary `0000` needs to be inverted to match against something `& 15` | |
limit to lowest 4 bits or a sinlge nibble, which is `15` or `1111`. | |
**/ | |
var zeroMask = ~code & 15; | |
/** | |
Is it `0010` & `code` inverted matching `0101`? Means the top | |
4 bits are `0010` which is always less than char `0` or decimal 48. | |
**/ | |
var lessThanZero = -(((code & 32) >> 5) & ((~code & 80) >> 4)); | |
/** | |
Combined with `lessThanZero`, this reduces the chance of a | |
false positive getting through. | |
**/ | |
var isZero = -((zeroMask & 1) & ((zeroMask & 2) >> 1) & ((zeroMask & 4) >> 2) & ((zeroMask & 8) >> 3)) & ~lessThanZero; | |
/** | |
Check the top 4 bits matches `0100` which means the ASCII character | |
is `@` or decimal 64 which is too large. | |
**/ | |
var greaterThanQuestionMark = -((code & 64) >> 6); | |
//var maybe09 = -((code & 48) >> 5); | |
/** | |
If any of the top 3 bits of the lowest 4 bits are set its too large. | |
**/ | |
var gte9 = -(((code & 8) >> 3) & ((code & 4) >> 2) & ((code & 2) >> 1)); | |
/** | |
Handles the `0` character, which at this point is binary `0000`. | |
**/ | |
var z = (isZero & code) | (~isZero & 0); | |
var a = (lessThanZero & 0) | (~lessThanZero & code); | |
var b = (greaterThanQuestionMark & 0) | (~greaterThanQuestionMark & code); | |
//var c = (maybe09 & code) | (~maybe09 & 0); | |
var d = (gte9 & 0) | (~gte9 & code); | |
code = z | a & b & /*c &*/ d & 15; | |
/** | |
Determines if the `base` should be increased. | |
**/ | |
var delta = code & 1; | |
delta |= (code & 2) >> 1; | |
delta |= (code & 4) >> 2; | |
delta |= (code & 8) >> 3; | |
delta |= (isZero & 1); | |
delta = -delta; | |
result += sign * (base * code); | |
base = (delta & (base * 10) | (~delta & base)); | |
index--; | |
} | |
return result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment