-1

I have to translate a CRC16 calculation from C to C# but get the message that I cannot implicitly convert type 'int' to 'bool' on the (crc & 0x8000) and on return (crc & 0xFFFF)

The code so far:

public unsafe short Crc16(string str)
{
    short crc = 0;

    for(int i = 0; i < str.Length; i++)
    {
        crc = (crc << 1) ^ str[i] ^ ((crc & 0x8000) ? 0x1021 : 0);
    }
    return (crc & 0xFFFF);
}

EDIT: Changed char parameter to string

Original C code

short Crc16( char *str )
{
    short crc=0;
    unsigned int i;
    for (i=0; i<strlen(str); i++)
        crc = (crc << 1) ^ *(str+i) ^ ((crc & 0x8000)? 0x1021:0 );
    return (crc & 0xffff);
}
user5825579
  • 105
  • 3
  • 15
  • https://msdn.microsoft.com/en-us/library/a569z7k8.aspx – Jodrell Mar 15 '16 at 15:52
  • 1
    It would be helpful to have the original C code, there are multiple problems with this code. However, C# does not implicitly treat numeric values are booleans. If you want to test if something is zero, you must specifically test for it. – vcsjones Mar 15 '16 at 15:53
  • Looks like a odd CRC calculation to me. – Jodrell Mar 15 '16 at 15:56
  • 2
    Looks like you haven't translated this properly. My guess is that in C the parameter was "char \*" - pointer to a string, it should be translated to "string", not "char" which is an integral type. Then "(str + i)\*" becomes str[i] etc. Need original code for more definitive answer. – Andrei Mar 15 '16 at 16:00
  • I've updated my answer to reflect the C code. – Berin Loritsch Mar 15 '16 at 16:11
  • Why is the question downvoted? – user5825579 Mar 15 '16 at 16:17

1 Answers1

3

In C, 0 and FALSE are synonymous, and any number that is not 0 is true. (reference)

To make the conversion you would do it something like this:

public short CalcCrc16(string str)
{
    short crc = 0;
    int i;

    unchecked
    {
        foreach(char c in str)
        {
            short exponent = (crc & 0x8000) != 0 ? 0x1021 : 0;
            crc = (crc << 1) ^ ((short)c) ^ exponent);
        }

        return (short)(crc & 0xFFFF);
    }
}

So now that we have the C code to work with, I changed the code sample I have here to match. Below is the explanation of the changes:

  • char* is the C equivalent of a string
  • The for loop is iterating over the characters *(str + i) can be rewritten as str[i], and is equivalent to C#'s str.GetChar(i)
  • The ternary condition is to determine whether the exponent is 0x1021 or 0.
  • I broke up the lines so you could see the algorithm a bit clearer.
  • I changed for(int i = 0; i < str.Length; i++) to a foreach on the characters because it was easier to understand.
Berin Loritsch
  • 11,400
  • 4
  • 30
  • 57
  • Appreciate the help but I still cannot implicityly convert type 'int' to 'short' on the `(crc << 1) ^ ((int)c) ^ exponent)` and `return (crc & 0xFFFF)`? – user5825579 Mar 15 '16 at 16:15
  • `*(str + i)` is the same as `str[i]` (not `*str[i]`) – Theodoros Chatzigiannakis Mar 15 '16 at 16:16
  • 1
    @user5825579 In C#, these operations return an `int` so you need to explicitly convert it to a `short`. For example, the last statement would become `return (short)(crc & 0xFFFF)`. Same with the assignment in the loop (and mind the parentheses). – Theodoros Chatzigiannakis Mar 15 '16 at 16:16