简体   繁体   中英

Why does the code in c# differs from the code in c when I write the same algorithm?

Function in C

unsigned long int ROTL(unsigned long int x, unsigned long int  y)
    {
        return ((x) << (y&(32 - 1))) | ((x) >> (32 - (y&(32 - 1))));
    }

Function in C#

 uint ROTL(uint x, uint y) 
   { 
       return ((x) << (int)(y & (32 - 1))) | ((x) >> (int)(32- (y & (32 - 1)))); 
   }

above functions do the same work and the same result for small numbers, but when I pass large numbers the result in C# differ from C.

Is there any problem in casting or in the function itself? Also I try to convert using

Convert.ToInt32()

Assuming unsigned long int translates to a unsigned 64bit integer you want to maybe go with C#s ulong instead of uint .

The main problem there is not the cast to int of the y-parameter, since it only takes the last 5 bits anyway. But when x is of type uint a bitshift with (worst case) 31 places exceeds its limits by far. Casting and returning it to ulong could do the trick.

ulong ROTL(uint x, uint y) 
{ 
    return (((ulong)x) << (int)(y & (32 - 1))) | (((ulong)x) >> (int)(32 - (y & (32 - 1)))); 
}

Please note, that I did not test this throughly, but only did some boundary tests: https://dotnetfiddle.net/0ETAEL

EDIT: When you expect the results to be bigger than 2^64 (or as Parameter values: ROTL(uint.MaxValue, 31) ) you should consider having a look at BigInteger .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM