Why Does Bit Shifting in Win32 API and C# BitConverter.ToInt32 Act Differently?

  • Thread starter Thread starter Silicon Waffle
  • Start date Start date
  • Tags Tags
    Bit
Click For Summary
SUMMARY

The discussion centers on the differences between the Win32 API's MAKEWORD macro and C#'s BitConverter.ToInt32 and ToInt16 methods. The MAKEWORD macro shifts the high byte by 8 bits to create a 16-bit integer, while BitConverter.ToInt32 processes four bytes into a 32-bit integer. The confusion arises from the varying shifts required for different data types, particularly when transitioning from 16-bit to 32-bit integers. The issue is compounded by improper casting of data types in custom implementations, which can lead to incorrect outputs.

PREREQUISITES
  • Understanding of Win32 API and its data types
  • Familiarity with C# and its BitConverter class
  • Knowledge of bitwise operations and shifting
  • Experience with data type casting in C and C#
NEXT STEPS
  • Study the Win32 API documentation for MAKEWORD and related macros
  • Learn about C# BitConverter methods, focusing on ToInt32 and ToInt16
  • Research bitwise operations and their applications in data manipulation
  • Explore proper casting techniques in C# to avoid data type issues
USEFUL FOR

Software developers, particularly those working with C# and Win32 API, as well as anyone involved in low-level data manipulation and serialization tasks.

Silicon Waffle
Messages
160
Reaction score
202
In Win32 API, I see the define macro MAKEWORD
#define MAKEWORD( h, l ) \
( ( ( WORD )( h ) << 8 ) | ( BYTE )( l ) )

Why does it make a shift of 8 bits ?

In C#, they have a BitConverter.ToInt32, which performs something similar to this Makeword and I use this 8 bit shift and it works correctly. But they also have ToInt16 which shifting like this works correctly too in some of my cases. I'm so confused about 32 and 16 in this case.
That is, at some places where I change makeword to make a shift of 16, it works correctly whereas at others where shifting 16 is required, the output then becomes incorrect since shifting 8 is more precise.

It looks like casting is the issue but how
PHP:
int MAKEWORD(const int*& val, const int& index)
{ 
   return (int)(((int)(val[index + 1]) << 16) + (short)(val[index]));
}
 
Last edited:
Technology news on Phys.org
The Win32API MAKEWORD is from a long time ago when Windows applications were 16-bit so a 'WORD' was a 16-bit integer (which would be considered a 'short' with modern compilers). It is taking two bytes (each 8 bits), a 'high' byte ('h') and a low byte ('l'), and shifting them into the proper places to make a 16-bit integer.

The ToInt32 function takes an array and an index and coverts the 4 bytes located from the index into a 32-bit integer. Useful for deserializing information from disk or a network.

I'm not sure what your function MAKEWORD is trying to do (and I'm not familiar with C#), but looks wrong to me because:
1. Your input 'val' is an array of integers. I think that it should be either an array of bytes or shorts.
2. You cast val[index+1] to an int but val[index] to a short.

If your goal was to make something like the MAKEWORD from Win32 API that works on byte arrays:
short MAKEWORD(const byte*& val, const int& index)
{
return ((short)val[index + 1]) << 8 + (short)(val[index]); // WARNING: I don't know C#
}
 

Similar threads

  • · Replies 7 ·
Replies
7
Views
2K
  • · Replies 7 ·
Replies
7
Views
4K
Replies
3
Views
10K
  • · Replies 3 ·
Replies
3
Views
4K
  • · Replies 5 ·
Replies
5
Views
6K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 7 ·
Replies
7
Views
3K
  • · Replies 30 ·
2
Replies
30
Views
7K
  • · Replies 16 ·
Replies
16
Views
5K
Replies
2
Views
3K