views:

1447

answers:

3

Hello,

the line "if(arg2 & 1)" in C++(arg2 is DWORD) is equal to "if(arg2 & 1==0)" in C#(arg2 is Uint32),right?

I am trying to translate a function from C++ to C#,but I get an error:

Operator '&' cannot be applied to operands of type 'uint' and 'bool'

I'd be also thankful if you could see further in the whole function for any other mistakes.

C++

DWORD Func_X_4(DWORD arg1, DWORD arg2, DWORD arg3)
{
LARGE_INTEGER result = {1, 0};
LARGE_INTEGER temp1 = {0};
LARGE_INTEGER temp2 = {0};
LARGE_INTEGER temp3 = {0};
LARGE_INTEGER temp4 = {0};
for(int x = 0; x < 32; ++x)
{
 if(arg2 & 1)
 {
  temp1.LowPart = arg3;
  temp1.HighPart = 0;
  temp2.QuadPart = temp1.QuadPart * result.QuadPart;
  temp3.LowPart = arg1;
  temp3.HighPart = 0;
  temp4.QuadPart = temp2.QuadPart % temp3.QuadPart;
  result.QuadPart = temp4.QuadPart;
 }
 arg2 >>= 1;
 temp1.LowPart = arg3;
 temp1.HighPart = 0;
 temp1.QuadPart *= temp1.QuadPart;
 temp2.LowPart = arg1;
 temp2.HighPart = 0;
 temp3.QuadPart = temp1.QuadPart % temp2.QuadPart;
 arg3 = temp3.LowPart;
 if(!arg2)
  break;
}
return result.LowPart;
}

Converted to C#

LARGE_INTEGER structure:

[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct LARGE_INTEGER
{
    [FieldOffset(0)]
    public Int64 QuadPart;
    [FieldOffset(0)]
    public UInt32 LowPart;
    [FieldOffset(4)]
    public Int32 HighPart;
}

Function:

public static UInt32 X4(UInt32 arg1, UInt32 arg2, UInt32 arg3)
    {
        LARGE_INTEGER result = new LARGE_INTEGER();
        result.LowPart = 1;
        result.HighPart = 0;
        LARGE_INTEGER temp1 = new LARGE_INTEGER();
        LARGE_INTEGER temp2 = new LARGE_INTEGER();
        LARGE_INTEGER temp3 = new LARGE_INTEGER();
        LARGE_INTEGER temp4 = new LARGE_INTEGER();
        for (int x = 0; x < 32; ++x)
        {
            if (arg1 & 1 ==0)
            {
                temp1.LowPart = arg3;
                temp1.HighPart = 0;
                temp2.QuadPart = temp1.QuadPart * result.QuadPart;
                temp3.LowPart = arg1;
                temp3.HighPart = 0;
                temp4.QuadPart = temp2.QuadPart % temp3.QuadPart;
                result.QuadPart = temp4.QuadPart;
            }
            arg2 >>= 1;
            temp1.LowPart = arg3;
            temp1.HighPart = 0;
            temp1.QuadPart *= temp1.QuadPart;
            temp2.LowPart = arg1;
            temp2.HighPart = 0;
            temp3.QuadPart = temp1.QuadPart % temp2.QuadPart;
            arg3 = temp3.LowPart;
            if (arg2==0)
                break;
        }
        return result.LowPart;
    }

This is what I'm not sure yet:

  1. Whether a DWORD in C++ is UInt32 or Int32 in C#?
  2. if(integer & integer) means if(integer and integer ==0)? //this is where the error i described above is placed.
  3. if(!integer) means if(integer != 0)?
  4. Why operator & cannot be used logically in C# ,meaning it requires a boolean?
  5. "LARGE_INTEGER result = {1, 0}" means result.lowpart is 1 and result.highpart is 0 or result.Quadpart = 1?

Thanks in advance!

+9  A: 

Where you write :

if (arg1 & arg2==0)

The compiler understands :

if (arg1 & (arg2==0))

You should write :

if ((arg1 & arg2) == 0)

This is the way the C++ statement should be translated to C# :

if (arg2 & 1) // C++ (arg2 is DWORD)
if ((arg2 & 1) != 0) // C# (arg2 is Uint32)

Or, in a more generic way:

if (Flags & FlagToCheck) // C++
if ((Flags & FlagToCheck) != 0) // C#


In C/C++, 0 is false, everything else is true.

  1. You should check the definition of DWORD, it should be (unsigned int), which is UInt32 in C#
  2. if (integer & integer), in C/C++ means "if the result of the bitwise and between the two integers is not 0" (0 is false, everything else is true).
  3. if (!integer) means if (integer == 0) (again, 0 is false, everything else is true)
  4. in C#, like in Java I think, booleans and numbers are two different things, you can only use booleans in "if" statements, there is not implicit conversion if you use an int : it won't compile.
  5. I'll leave this one to someone else, I'd need to test to be sure...
ybo
John
re "arg2 Is that right? I thought C/C++ "true" was "non-zero"; so should be "(arg2
Marc Gravell
Jim Mischel
@Jim - ah, right. True, but just *asking* for somebody to fall into a copy/paste trap...
Marc Gravell
@Marc, Thanks for you remark, I'll edit.
ybo
@ybo,done your question is accepted!
John
@Marc: yeah. "!= 0" is definitely the way to go.
Jim Mischel
+4  A: 
  1. DWORD is uint32_t in C++, thus UInt32 in C#.
  2. if(a & b) converts to if((a & b) != 0). != is evaluated before & thus the & expression needs parentheses around it.
  3. if(x) converts to if(x != 0)
  4. & is a 'bitwise and' in C#, like in C++.
  5. Depends on your C++ structure.
strager
There's no structure in C++,LARGE_INTEGER is a build it structure.I couldn't find it.
John
@John, Then I have no idea. Look in your header files for LARGE_INTEGER; I doubt it's built into the compiler.
strager
I figured it out,Low part is first and High part is second,meaning lowpart=1 and highpart=0.Thanks,I accepted your answer!
John
You'll find information about LARGE_INTEGER here: http://msdn.microsoft.com/en-us/library/aa383713(VS.85).aspx
Jim Mischel
+1  A: 

5 - It means both. Because LowPart and HighPart are just "windows" into QuadPart's memory, when result.LowPart == 1 and Result.HighPart == 0, then result.QuadPart will be equal to 1.

Jim Mischel
I digged your answer aswell,i figured out how LARGE_INTEGERS work already,but I appreciate that you helped,so +1 :)
John