Error converting Int64 to Int32 and vice versa
-
I'm using the following code to roundtrip a value between one Int64 var and two In32 vars.
public static Int64 Int64FromPersistentIDs(int highID, int lowID)
{
return (((Int64)highID << 32) + (Int64)lowID);
}public static void PersistentIDsFromInt64(Int64 longID, ref int highID, ref int lowID)
{
lowID = (int)(longID & 0xFFFFFFFF);
highID = (int)((longID >> 32) & 0xFFFFFFFF);
}This code roundtrips well when
highID
is positive, and whenhighID
is negative and 9 digits, but it fails as soon ashighID
is negative and 10 digits - the highID comes back as off by one (one too large). What am I doing wrong here? -
I'm using the following code to roundtrip a value between one Int64 var and two In32 vars.
public static Int64 Int64FromPersistentIDs(int highID, int lowID)
{
return (((Int64)highID << 32) + (Int64)lowID);
}public static void PersistentIDsFromInt64(Int64 longID, ref int highID, ref int lowID)
{
lowID = (int)(longID & 0xFFFFFFFF);
highID = (int)((longID >> 32) & 0xFFFFFFFF);
}This code roundtrips well when
highID
is positive, and whenhighID
is negative and 9 digits, but it fails as soon ashighID
is negative and 10 digits - the highID comes back as off by one (one too large). What am I doing wrong here?int64 is up to 19 digits and Max/Min value is +/-9,223,372,036,854,775,808 , where int32 is only 10 and Max/Min value is +/-2,147,483,647 what your'e doing is spilling bits off by (int)(longID & 0xFFFFFFFF); int is Int32 and not int64 :):)
Have Fun Never forget it
-
int64 is up to 19 digits and Max/Min value is +/-9,223,372,036,854,775,808 , where int32 is only 10 and Max/Min value is +/-2,147,483,647 what your'e doing is spilling bits off by (int)(longID & 0xFFFFFFFF); int is Int32 and not int64 :):)
Have Fun Never forget it
-
I'm using the following code to roundtrip a value between one Int64 var and two In32 vars.
public static Int64 Int64FromPersistentIDs(int highID, int lowID)
{
return (((Int64)highID << 32) + (Int64)lowID);
}public static void PersistentIDsFromInt64(Int64 longID, ref int highID, ref int lowID)
{
lowID = (int)(longID & 0xFFFFFFFF);
highID = (int)((longID >> 32) & 0xFFFFFFFF);
}This code roundtrips well when
highID
is positive, and whenhighID
is negative and 9 digits, but it fails as soon ashighID
is negative and 10 digits - the highID comes back as off by one (one too large). What am I doing wrong here?Can you give an example that does not work? Using your methods, I plugged in some numbers and, round trip, it works just fine (even without changing the types to unsigned).
static void Main(string\[\] args) { int highID = -1234567890; int lowID = 123456789; Console.WriteLine("Build 64-bit ID:"); long longID = Int64FromPersistentIDs(highID, lowID); Console.WriteLine("highID: ({0,20})", highID); // PrintBits(highID, 32); Console.WriteLine(" lowID: ({0,20})", lowID); // PrintBits(lowID, 32); Console.WriteLine("longID: ({0,20})", longID); // PrintBits(longID, 64); Console.WriteLine("\\nExtract-32 bit IDs:"); PersistentIDsFromInt64(longID, ref highID, ref lowID); Console.WriteLine("longID: ({0,20})", longID); // PrintBits(longID, 64); Console.WriteLine("highID: ({0,20})", highID); // PrintBits(highID, 32); Console.WriteLine(" lowID: ({0,20})", lowID); // PrintBits(lowID, 32); } public static Int64 Int64FromPersistentIDs(int highID, int lowID) { return (((Int64)highID << 32) + (Int64)lowID); } public static void PersistentIDsFromInt64(Int64 longID, ref int highID, ref int lowID) { lowID = (int)(longID & 0xFFFFFFFF); highID = (int)((longID >> 32) & 0xFFFFFFFF); }
Outputs:
Build 64-bit ID:
highID: ( -1234567890)
lowID: ( 123456789)
longID: (-5302428712118268651)Extract-32 bit IDs:
longID: (-5302428712118268651)
highID: ( -1234567890)
lowID: ( 123456789) -
Can you give an example that does not work? Using your methods, I plugged in some numbers and, round trip, it works just fine (even without changing the types to unsigned).
static void Main(string\[\] args) { int highID = -1234567890; int lowID = 123456789; Console.WriteLine("Build 64-bit ID:"); long longID = Int64FromPersistentIDs(highID, lowID); Console.WriteLine("highID: ({0,20})", highID); // PrintBits(highID, 32); Console.WriteLine(" lowID: ({0,20})", lowID); // PrintBits(lowID, 32); Console.WriteLine("longID: ({0,20})", longID); // PrintBits(longID, 64); Console.WriteLine("\\nExtract-32 bit IDs:"); PersistentIDsFromInt64(longID, ref highID, ref lowID); Console.WriteLine("longID: ({0,20})", longID); // PrintBits(longID, 64); Console.WriteLine("highID: ({0,20})", highID); // PrintBits(highID, 32); Console.WriteLine(" lowID: ({0,20})", lowID); // PrintBits(lowID, 32); } public static Int64 Int64FromPersistentIDs(int highID, int lowID) { return (((Int64)highID << 32) + (Int64)lowID); } public static void PersistentIDsFromInt64(Int64 longID, ref int highID, ref int lowID) { lowID = (int)(longID & 0xFFFFFFFF); highID = (int)((longID >> 32) & 0xFFFFFFFF); }
Outputs:
Build 64-bit ID:
highID: ( -1234567890)
lowID: ( 123456789)
longID: (-5302428712118268651)Extract-32 bit IDs:
longID: (-5302428712118268651)
highID: ( -1234567890)
lowID: ( 123456789)Sure: The following High / Low combination: -1173074781 / -1181223073 was round-tripping back as -1173074782 / -1181223073 (note the High Order output is one more than the input.) I determined that that code which builds the 64bit INT was the culprit, here's why. These IDs are passed to me by an application that actually stores a 64 bit number in it's XML database. However, instead of passing me the 64bit number, it passes me two 32 bit numbers. I looked inside the database for the record I was querying, and the 64bit number stored there is: BA144CA3B997F75F But my code (
return (((Int64)highID << 32) + (Int64)lowID)
) was returning BA144CA2B997F75F (note the difference at the 8th digit - the 2 should be a three) So I was getting a bad 64 bit number from my code. I changed my units to UInt64, and my code started returning a 64 bit number which matched that number stored in the database. I don't know exactly why it was failing, but I could tell it was a "size" issue, because some inputs were returning the correct 64 bit numbers (as validated in the database), and some were not.