Problem parse integer within JSON response - string

I have following JSON response string
{"firstname":"a","lastname":"a","jobtitle":"software developer","companyname":"abc","mobileno":9461438988}
i cant get the string value for 'mobileno' field
This is how i read the 'mobileno' field
self.dispPhone = [NSString stringWithFormat:#"%# ",[parsedProfileData valueForKey:#"mobileno"]];
the string here becomes some garbage value '2147483647' when i NSLog it

First of all, a phone number is not an integer. Phone numbers may start with significant 0s or +. For example, in Germany 00.. is international, 0 national, and any other digit regional.
The returned value is the highest possible 31 bit number. Since your JSON encoder decodes to signed 32bit ints, this is the best value it can give you.
To solve this problem, format phone numbers as strings in the original.

The number 9,461,438,988 cannot be stored in a 32-bit value, so it's being truncated to fit.
You should store your phone numbers as the strings they are (just like ZIP codes).
In general, anything that you don't want to do arithmetic or numeric comparison on (< or >) is a string, not a number.

Related

HEX2OCT formula in MS Excel returns incorrect result

While converting the hexadecimal value "FFFFFFFF00" into octal value using Hex2Oct of MS Excel, it should return "Error string" as per the rules mentioned here:
If number is negative, HEX2OCT ignores places and returns a 10-character octal number.
If number is negative, it cannot be less than FFE0000000, and if number is positive, it cannot be greater than 1FFFFFFF.
If number is not a valid hexadecimal number, HEX2OCT returns the #NUM! error value.
If HEX2OCT requires more than places characters, it returns the #NUM! error value.
If places is not an integer, it is truncated.
If places is nonnumeric, HEX2OCT returns the #VALUE! error value.
If places is negative, HEX2OCT returns the #NUM! error value.
But it computes and returns as "7777777400" without considering the rules/remarks mentioned in the link.
For example:
While calculating HEX2OCT,
As per Excel rule, If number is positive, it cannot be greater than 1FFFFFFF(hex)<->3777777777(oct)<->536870911(decimal).
But while calculating the HEX2OCT for FFFFFFFF00(hex) <-> 7777777400(oct) <-> 1099511627520(decimal).
Here the hex value FFFFFFFF00 is greater than 1FFFFFFF, but MS Excel does not return the error string instead it returns the converted octal value.
Can anyone explain why?
FFFFFFFF00 is actually well within the range of hex2oct because it is a negative number.
According to that documentation the largest negative number it can handle is FFE0000000 which when converted to decimal is -536870912. Converting your "big" hex over to decimal yields -256.
The reason the value of FFFFFFFF00 looks so big is because it's a negative number. The first bit is set to 1 (when converted to binary) which signifies that the number is negative. Negatives are computed in binary using two's complement which is found by flipping each bit and then adding 1 to the number.
Undoing the two's complement:
For your big number, the binary representation is:
1111111111111111111111111111111100000000
Subtracting 1:
1111111111111111111111111111111011111111
Flipping all the bits:
0000000000000000000000000000000100000000
Which is 256
So.. basically if the hex looks big, but the first bit is 1 then it's actually a small negative and well within your range of allowable values.
Lastly, when you hex2oct you don't get a negative sign for these because we are still not in decimal notation. The first bit of your octal is still a 1 (when converted to binary) since it's still the same number, just represented in a different counting system.
The clue lies earlier in the documentation page you quote:
The HEX2OCT function syntax has the following arguments:
Number Required. The hexadecimal number you want to convert. Number cannot contain more than 10 characters. The most significant
bit of number is the sign bit. The remaining 39 bits are magnitude
bits. Negative numbers are represented using two's-complement notation.
The hex value FFFFFFFF00 corresponds the binary value
1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
and as the documentation says, "the most significant bit is the sign bit ... two's complement notation". So this value represents a negative number. By the rules of two's complement, it actually represents -256. And this is fine, because it is not "less than FFE0000000", as FFE0000000 is -2097152.
If you actually want to treat FFFFFFFF00 as an unsigned quantity, and get the octal representation of decimal 1099511627520, you'll need to use another method.

Space-efficient way to encode numbers as sortable strings

Starting with a list of integers the task is to convert each integer into a string such that the resulting list of strings will be in numeric order when sorted lexicographically.
This is needed so that a particular system that is only capable of sorting strings will produce an output that is in numeric order.
Example:
Given the integers
1, 23, 3
we could convert the to strings like this:
"01", "23", "03"
so that when sorted they become:
"01", "03", "23"
which is correct. A wrong result would be:
"1", "23", "3"
because that list is sorted in "string order", not in numeric order.
I'm looking for something more efficient than the simple zero-padding scheme. In order to cover all possible 32 bit integers we'd need to pad to 10 digits which is inefficient.
For integers, prefix each number with the length. To make it more readable, use 'a' for length 1, and 'b' for length 2. Example:
non-encoded encoded
1 "a1"
3 "a3"
23 "b23"
This scheme is a bit simpler than prefixing each digit, but only works with numbers, not numbers mixed with text. It can be made to work for negative numbers as well, and even BigDecimal numbers, using some tricks. I wrote an implementation in Apache Jackrabbit 2.x, to make BigDecimal indexable (sortable) as text. For that, I used a format that only uses the characters '0' to '9' and consists of:
one character for: signum(value) + 2
one character for: signum(exponent) + 2
one character for: length(exponent) - 1
multiple characters for: exponent
multiple characters for: value (-1 if inverted)
Only the signum is encoded if the value is zero. The exponent is not encoded if zero. Negative values are "inverted" character by character (0 => 9, 1 => 8, and so on). The same applies to the exponent.
Examples:
non-encoded encoded
0 "2"
2 "322" (signum 1; exponent 0; value 2)
120 "330212" (signum 1; exponent signum 1, length 1, value 2; value 12)
-1 "179" (signum -1, rest inverted; exponent 0; value 1 (-1, inverted))
Values between BigDecimal(BigInteger.ONE, Integer.MIN_VALUE) and BigDecimal(BigInteger.ONE, Integer.MAX_VALUE) are supported.
TL;DR
Encode digits according to their order of magnitude (OM) and other characters so they sort as desired, relative to numbers: jj-a123 would be encoded zjzjz-zaC1B2A3
Longer explanation
This would depend somewhat upon the sorting algorithm that will finally be used to sort and how one would want any given punctuation characters to be sorted in relation to letters and numbers, but if it's "ascii-betical" or similar, you could encode each digit of a number to represent its order of magnitude (OM) in the number, while encoding other characters such that they would sort according to your desired sort order.
For simplicity, I would suggest beginning with encoding every non-numeric character with a "high" value (e.g. lower case z or even ~ if final value is ASCII), so that it sorts after encoded digits. Then cache each digit encountered until another non-numeric is encountered, then encode each cached digit with a value representing its OM. If the number 12945 was encountered in between non-numerics, you would output an E to encode an OM of 5, then the digit that is that order of magnitude, 1, followed by the next OM of 4 (D) and its associated digit, 2. Continue until all numeric digits have been flushed, then continue with non-numerics.
Non-numerics would be treated individually and ranked relative to the OM of digits. If it is desired for them to sort "above" numbers (perhaps the space character or certain others deemed special) they would be encoded by prepending a low-value character (like the space character, if final value will be treated and sorted as ASCII). When/if another numeric is encountered, begin caching and encode according to OM once all consecutive numerics are cached.
Alternately, processing the string in reverse order would preclude the need to cache numbers except for a single "is it a digit?" test and "is the last character a digit?" test. If the first is not true, then use (one of?) the "non-digit" OM character(s). If the first test is true then use the lowest-OM "digit" character (A in my examples). If both tests are true, then increment your OM character (A -> B or E -> F) before use.
Certain levels of additional filtering - or even translation - could be applied. If one wanted to allow accurate sorting based upon Roman numerals, one could encode them as decimal (or even hexadecimal) numbers with an appropriate OM.
Treating decimal points (either periods or commas, depending) as actual decimal separators, and distinct from other punctuation would probably be beyond the true utility of this encoding scheme, as alphanumeric fields seldom use a period or comma as a decimal separator. If it is desired to use them that way, the algorithm would simply detect a decimal separator (either period or comma as appropriate, in between digits) and not encode the numeric portion after that separator as anything but normal text. Fractional portions are actually sorted correctly during a normal ASCII based sort, because more digits represents greater precision - not greater magnitude.
Examples
non-encoded encoded
----------- -------
12345 E1D2C3B4A5
a100 zaC1B0A0
a20 zaB2A0
a2000 zaD2C0B0A0
x100.5 zxC1B0A0z.A5
x100.23 zxC1B0A0z.B2A3
1, 23, 3 A1z,z B2A1z,z A3
1, 2, 3 A1z,z A2z,z A3
1,2,3 A1z,A2z,A3
Potential advantages
Going somewhat beyond simple numeric sorting, some advantages to this encoding method would be several aspects of flexibility with final effective sort order - you are essentially encoding a category for each character - digits get a category based upon their position within the greater string of digits known as a number, while other characters are simply told to sort in their normal way (e.g. ASCII), but after numbers. Any exceptions that should sort before numbers or in other orders would be in one or more additional categories. ASCII can effectively be re-encoded to sort in a non-ASCII way:
You could encode lower case letters to sort before or along with upper case letters. To switch the lower and upper cases, you encode lower case letters with a y and upper case letters with a z. For a pseudo-case-insensitive sort, categorizing both A and a with the same encoding character would sort both of them before B and b, though A would nonetheless always sort before a
If you want Extended ASCII characters (e.g. with diacritics) to sort along with their ASCII cousins, you encode À, Á, Â, Ã, Ä, Å, and Æ along with A by using an a as the OM character, encode B, C, and Ç with a b, and E, È, É, Ê, and Ë with a c, etc. The same intra-category sort order caveat still applies, and some decisions need to be made on characters like capital Eth, and to a certain extent others like Thorn, and Sharp S (Ð, Þ, and ß respectively) as to whether they will sort based on similarities in appearance or pronunciation, or instead more properly perhaps, alphabetical order.
Small advantage of being basically human-readable, with effort
Caveats
Though this allows many 'categories' of characters to be defined, be sure to remember that each order of magnitude for digits is its own category - you need to know that the data will not contain numbers that are greater in OM than approximately 250, depending upon how many other categories you wish to define (ASCII 0 is reserved for storing strings, and there needs to be at least one other character to indicate "not a digit" - at least for alphanumeric data - making the maximum perhaps 254 orders of magnitude), but that should be plenty for any situation I can imagine. I'm not sure what other issues quantum computing will bring about, but there's probably a quantum solution to it, whatever it is.
Finally, if the hyphen is encoded as a non-numeric character, and all non-numerics are encoded with a higher OM than digits, negative numbers would be encoded as greater than any positive number. The hyphen should be encoded as a lower-than-digit-OM (perhaps only when preceding a digit) if negative numbers need to be sorted correctly according to magnitude.
Since the ASCII code of A is greater than 9, you could encode them as hexadecimal strings.
The integers
1, 23, 3
can be encoded as
00000001, 00000017, 00000003
and 32-bit integers can always be encoded as 8-character strings. (assume unsigned)

How do I convert a 64bit number to hexadecimal in excel?

I'm trying DEC2HEX(1000000000050000000) but it comes out as #NUM! as the number is too large for this function.
Is there another function I could use to turn this number into hexadecimal?
If you want to convert a decimal number to a 64 bit hex string, assuming that the decimal number is in cell A1 you can use the following:
=CONCATENATE(DEC2HEX(A1/2^32),DEC2HEX(MOD(A1,2^32),8))
This will work up to decimal value of 18,446,744,073,709,500,000 or hex value of 0xfffffffffffff800.
Bonus:
To convert from hex string to decimal, assuming that the 64bit hex string is in cell A1 and contains 16-characters then you can use the following:
=HEX2DEC(LEFT(A1,8))*2^32+HEX2DEC(RIGHT(A1,8))
You can adjust the number of characters in the LEFT(text,[num_chars]) to better suit your needs.
If your hex string has a 0x then you can use the following:
=HEX2DEC(MID(A1,3,8))*2^32+HEX2DEC(RIGHT(A1,8))
I found a simple solution for converting HEX to DEC and vice versa without the limits of characters.
HEX to DEC: use DECIMAL(input number or cell coordinates, input base number)
Case 1: I want to convert hex value "3C" to decimal, the formula is DECIMAL(3C, 16).
Case 2: I want to convert binary value "1001" to decimal, the formula is DECIMAL(1001, 2).
DEC to HEX: use BASE(input number or cell coordinates, output base number)
Case 1:I want to convert number value "1500" to hexadecimal, the formula is BASE(1500, 16)
Case 2:I want to convert number value "1500" to binary, the formula is BASE(1500, 2)
The DEC2HEX function has a limit of 549,755,813,887, try this formula it works for numbers up to 281,474,976,710,655.
=DEC2HEX(A7/(16^9),3)&DEC2HEX(MOD(A7,16^9),9)
There is a free add-in available that will handle that: Xnumbers
Seems to work OK:
=cvDecBase("1000000000050000000",16) --> DE0B6B3AA5EF080
Long formula but it is working for 64-HEX characters:
=HEX2DEC(MID(A24,1,8))*2^512 *(4) +HEX2DEC(MID(A24,9,8))*2^512 *(2) +HEX2DEC(MID(A24,17,8))*2^512+HEX2DEC(MID(A24,25,8))*2^256+HEX2DEC(MID(A24,33,8))*2^128+HEX2DEC(MID(A24,41,8))*2^64+HEX2DEC(MID(A24,49,8))*2^32+HEX2DEC(MID(A24,57,8))
please note: (*4) = *4 (remove brackets) and: (*2) = *2 (remove brackets)
also note: all 64 character must be present like the following example:
0000000000000000000000000000000000000000000000000000000000000fd1

Extract specific data from field in Access table

Every 2 weeks I need to import an excel file into an access 2007 database. The 2nd cell in the excel file A2 contains always different information. It always start with AS OF PAY PERIOD XX, where XX stands for the pay period. When imported into an access table I need to extract the pay period and it seems that the pay period is always in position 18, a payperiod is always 2 chars in length. Is there an easy way with a string function to extract that information. Thanks.
http://office.microsoft.com/en-us/access-help/mid-function-HA001228881.aspx
Returns a Variant (String) containing a specified number of characters from a string.
Syntax
Mid(string, start [, length ] )
The Mid function syntax has these arguments :
string - Required. string expression from which characters are returned. If string contains Null, Null is returned.
start - Required. Long - Character position in string at which the part to be taken begins. If start is greater than the number of characters in string, Mid returns a zero-length string ("").
length - Optional. Variant (Long) - Number of characters to return. If omitted or if there are fewer than length characters in the text (including the character at start), all characters from the start position to the end of the string are returned.
Use the MID statment within a query, a SQL statement, or on the field data element from a recordset process.

Substring a text using MOVEL function in RPG

Question:
Is it save to get substring n characters from a text in RPG using MOVEL function which take a text with length x and store it to a variable with capacity n?
Or the only save way to get the first n character is using SUBST?
The background of the question is one of my colleague getting the first 3 characters from a database with 30 char in length is using MOVEL to a variable with length only 3 char (like truncating the rest of it). The strange way, sometimes the receive variable is showing minus character ('-'), sometimes doesn't. So I assume using MOVEL is not a safe way. I am thinking like string in C which always terminated by '\0', you need to use strcpy function to get the copy save, not assigning using = operator.
Anybody who knows RPG familiar with this issue?
MOVEL should work. RPG allows several character data types. Generally speaking, someone using MOVEL will not be dealing with null terminated strings because MOVEL is an old technique and null terminated strings are a newer data type. You can read up on the MOVEx operations and the string operations in the RPG manual. To get a better answer, please post your code, including the definitions of the variables involved.
EDIT: Example of how MOVEL handles signs.
dcl-s long char(20) inz('CORPORATION');
dcl-s short char(3) inz('COR');
dcl-s numb packed(3: 0);
// 369
c movel long numb
dsply numb;
// -369
c movel short numb
dsply numb;
*inlr = *on;
With signed numeric fields in RPG the sign is held in the zone of the last byte of the field. So 123 is X'F1F2F3' but -123 is X'F1F2D3'. If you look at those fields as character strings they will have 123 and 12L in them.
In your program you are transferring something like "123 AAAAAL" to a 3 digit numeric field so you get X'F1F2F3' but because the final character is X'D3' that changes the result to have a zone of D i.e. X'F1F2D3'
You anomaly is dependent on what the 30th character contains. If it is } or any capital letter J to R then you get a negative result. [It doesn't matter whether the first 3 characters are numbers or letters because it is only the second half of the byte, the digit, that matters in your example.]
The IBM manuals say:
If factor 2 is character and the result field is numeric, a minus zone is moved into the rightmost position of the result field if the zone from the rightmost position of factor 2 is a hexadecimal D (minus zone). However, if the zone from the rightmost position of factor 2 is not a hexadecimal D, a positive zone is moved into the rightmost position of the result field. Other result field positions contain only numeric characters.
Don

Resources