In article news:11**********************@n51g2000cwc.googlegr oups.com,
Tim Clark wrote:
How about:
public static Int64 ToInt64(Int32 low, Int32 high)
{
Int64 x = high;
x <<= 32;
x = x | low;
}
Quite, except that Russell's definition of 'low' and 'high' may be
surprising... The output that I get, with the first line from Russell's
function, I get:
low & high = result
11223344 & aabbccdd = 11223344aabbccdd
11223344 & aabbccdd = 11223343aabbccdd
11223344 & aabbccdd = 11223343aabbccdd
So low is (Intel-wise) high, and high low... :-)
Out of interest I created two slighty different methods of doing it:
public static Int64 Alan1_ToInt64(Int32 low, Int32 high)
{
const Int64 Bit32 = 0x100000000;
System.Diagnostics.Debug.Assert(Bit32 == (0x1L + UInt32.MaxValue));
System.Diagnostics.Debug.Assert(Bit32 == (0x1L << 32));
Int64 result = high + Bit32 * low;
return result;
}
public static Int64 Alan2_ToInt64(Int32 low, Int32 high)
{
Int64 result = high | ((Int64)low << 32);
return result;
}
And on inspecting the disassembly of both, assuming my unqualified
reading of x86 assembler is correct, both are JITted to a x86 shift
operation... So chose either depending on which is more
'understandable'.
Then I re-looked at my results and saw in the latter two lines: 11, 22,
33, 43!!!! WTF?
The I inputted all the functions that have been posted here so far, and
I get:
low & high = result
11223344 & aabbccdd = 11223344aabbccdd
11223344 & aabbccdd = 11223343aabbccdd
11223344 & aabbccdd = 11223343aabbccdd
11223344 & aabbccdd = aabbccdd11223344
11223344 & aabbccdd = aabbccdd11223344
11223344 & aabbccdd = aabbccdd11223344
low & high = result
aabbccdd & 11223344 = aabbccdd11223344
aabbccdd & 11223344 = aabbccdd11223344
aabbccdd & 11223344 = aabbccdd11223344
aabbccdd & 11223344 = ffffffffaabbccdd
aabbccdd & 11223344 = ffffffffaabbccdd
aabbccdd & 11223344 = 11223343aabbccdd
!!! It's past my bedtime, so I leave it for someone else to explain...
Unless I've got a buggy CPU, and only I get this behaviour. I haven't
gone back an re-inspected the assembler for instance.
The code it thus:
{
public void DoIt()
{
const Int32 low = 0x11223344, high =
unchecked((Int32)0xaabbccdd);
DoItWith(low, high);
const Int32 high2 = 0x11223344, low2 =
unchecked((Int32)0xaabbccdd);
DoItWith(low2, high2);
}
private static void DoItWith(Int32 low, Int32 high)
{
Console.WriteLine("{0,8} & {1,8} = {2}", "low", "high",
"result");
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
RussellsOriginal_ToInt64(low, high));
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
Alan1_ToInt64(low, high));
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
Alan2_ToInt64(low, high));
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
TimClark_ToInt64(low, high));
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
TimClark_ToInt64(low, high));
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
rdrunner_FastToInt64(low, high));
}
public static Int64 Alan1_ToInt64(Int32 low, Int32 high)
{
const Int64 Bit32 = 0x100000000;
System.Diagnostics.Debug.Assert(Bit32 == (0x1L +
UInt32.MaxValue));
System.Diagnostics.Debug.Assert(Bit32 == (0x1L << 32));
Int64 result = high + Bit32 * low;
return result;
}
public static Int64 Alan2_ToInt64(Int32 low, Int32 high)
{
Int64 result = high + ((Int64)low << 32);
return result;
}
public static Int64 TimClark_ToInt64(Int32 low, Int32 high)
{
Int64 x = high;
x <<= 32;
// Warning: Bitwise-or operator used on a sign-extended
operand; consider casting to a smaller unsigned type first
x = x | low;
return x;
}
public static Int64 rdrunner_FastToInt64(Int32 low, Int32 high)
{
return ((Int64)(high) << 32) + low;
}
public static Int64 TomDacon_ToInt64(Int32 low, Int32 high)
{
return (Int64)(((UInt64)high << 32) | (UInt32)low);
}
public static Int64 RussellsOriginal_ToInt64(Int32 low, Int32
high)
{
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);
Byte[] bytes = new Byte[8];
Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);
return BitConverter.ToInt64(bytes, 0);
}
}
Alan
Russell Mangel wrote:
>Can someone show me how to speed this up?
1. Whats the fastest way for Unsafe C#?
2. What the fastest way for Safe C#?
public static Int64 ToInt64(Int32 low, Int32 high)
{
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);
Byte[] bytes = new Byte[8];
Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);
return BitConverter.ToInt64(bytes, 0);
}
Thanks.
Russell Mangel
Las Vegas, NV
PS
The winner will receive keys for a Mercedes Benz.
--
Alan J. McFarlane
http://www.alanjmcf.me.uk/
Please follow-up in the newsgroup for the benefit of all.