Purpose of casting -1 to uint32? - c#

This is probably a really silly question to experienced C++ developers, but what is the purpose of casting a -1 to uint32? I am translating a program from C++ to C# and there are many occasions when I see something like this:
static const uint32 AllTypes = static_cast<uint32>(-1);
What exactly does this do? How can the same be accomplished in C#?

On systems using two's complement, casting -1 to unsigned gives the highest value an unsigned number can represent.
In C# you can use unchecked((UInt32)-1) or better: UInt32.MaxValue. This is well defined behavior, and works on all CPU architectures.
According to the thread rve linked, casting -1 to unsigned results in all bits being set on all architectures in C++.

How can the same be accomplished in C#
uint AllTypes = uint.MaxValue;

I guess it's used to have all bits to 1. Useful when we use tagged data. Probably each elementary type it's given a bit, and 'complex' types (arrays, for instance) get their own.

Related

How and when to use :short in C#?

I want to know when to use :short in C#?
Please help I want to use it instead of int.
Is using short a good or bad idea?
short - aka Int16 - has some very real but limited uses.
Example scenarios:
when the input value is limited to 16-bits, and you don't want to violate an invariant (perhaps because it maps to a database column that is 16 bits - smallint in SQL Server, for example)
declaring an enum that is : short for similar reasons
because you're implementing an algorithm that demands 16-bit wrapping behaviour - CRC-16, for example
when you are writing a struct with explicit layout that needs to map a very specific configuration (usually related to C/C++ mapping)
It is unusual, but by no means unexpected. Similarly: byte, sbyte, ushort, uint, long, ulong, etc.
int is a great default, but it is by no means the only option.
You will rarely need to use short, and I think it's reasonable to consider its use "bad" unless there's a compelling reason for using it.
int will generally perform better than short on modern CPUs.
For example, you may need to use short in a struct used to interoperate with legacy unmanaged code.
It's more optimal solution for memory saving to use proper type, because short has 16 bits size and int has 32 bits size.

Confusion between Word16 and UWord16

I'm porting some C code to C#. I'm seeing a lot of Word16, Word32 usage, along with UWord16and UWord32.
I know Word32 is an unsigned 32bit int type, but what could have been the need to write it with a different name UWord32? Am I missing something here? Is it different from Word32 in some manner?
Also, WORD32 can I just replace its usage in C# with int? If not, why?
This Source, says WORD is an unsigned integral type. Yes the source is of Haskell, I couldn't find any other documentation explaining the datatype WORD.
but what could have been the need to write it with a different name UWord32?
This is an unsigned 32 bit integer type.
In general, you can likely replace (moving to C#):
WORD32 -> int (Int32)
UWORD32 -> uint (UInt32)
WORD16 -> short (Int16)
UWORD16 -> ushort (UInt16)
This is, however, all speculation based on my expectations given the naming scheme you've shown.
Note that, if you're using Windows Data Types, WORD -> ushort, and DWORD -> uint. Signed types are INT/INT32 -> int, and then INT16 -> short, INT64 -> long, etc.
That being said, all of these options are all defines in C or C++, and not "native" (language defined) types. Your code could define WORD to represent an unsigned 64 bit integer, if it chose. As such, you need to look at where the defines are coming from (I listed the Windows API standards here).
I know Word32 is an unsigned 32bit int type, but what could have been the need to write it with a different name UWord32?
If this is the case, there is likely no need to have two definitions for the same type. It may be that two headers you are using define things slightly different. Again, you'd need to check the headers you're using that define these types, and see how they're specified.

using uint vs int [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have observed for a while that C# programmers tend to use int everywhere, and rarely resort to uint. But I have never discovered a satisfactory answer as to why.
If interoperability is your goal, uint shouldn't appear in public APIs because not all CLI languages support unsigned integers. But that doesn't explain why int is so prevalent, even in internal classes. I suspect this is the reason uint is used sparingly in the BCL.
In C++, if you have an integer for which negative values make no sense, you choose an unsigned integer.
This clearly signifies that negative numbers are not allowed or expected, and the compiler will do some checking for you. I also suspect in the case of array indices, that the JIT can easily drop the lower bounds check.
However, when mixing int and unit types, extra care and casts will be needed.
Should uint be used more? Why?
int is shorter to type than uint.
Your observation of why uint isn't used in the BCL is the main reason, I suspect.
UInt32 is not CLS Compliant, which means that it is wholly inappropriate for use in public APIs. If you're going to be using uint in your private API, this will mean doing conversions to other types - and it's typically easier and safer to just keep the type the same.
I also suspect that this is not as common in C# development, even when C# is the only language being used, primarily because it is not common in the BCL. Developers, in general, try to (thankfully) mimic the style of the framework on which they are building - in C#'s case, this means trying to make your APIs, public and internal, look as much like the .NET Framework BCL as possible. This would mean using uint sparingly.
Normally int will suffice. If you can satisfy all of the following conditions, you can use uint:
It is not for a public API (since uint is not CLS compliant).
You don't need negative numbers.
You (might) need the additional range.
You are not using it in a comparison with < 0, as that is never true.
You are not using it in a comparison with >= 0, as that is never false.
The last requirement is often forgotten and will introduce bugs:
static void Main(string[] args)
{
if (args.Length == 0) return;
uint last = (uint)(args.Length - 1);
// This will eventually throw an IndexOutOfRangeException:
for (uint i = last; i >= 0; i--)
{
Console.WriteLine(args[i]);
}
}
1) Bad habit. Seriously. Even in C/C++.
Think of the common for pattern:
for( int i=0; i<3; i++ )
foo(i);
There's absolutely no reason to use an integer there. You will never have negative values. But almost everyone will do a simple loop that way, even if it contains (at least) two other "style" errors.
2) int is perceived as the native type of the machine.
I prefer uint to int unless a negative number is actually in the range of acceptable values. In particular, accepting an int param but throwing an ArgumentException if the number is less than zero is just silly--use a uint!
I agree that uint is underused, and I encourage everyone else to use it more.
I program at a lower level application layer where ints rarely get above 100, so negative values are not an issue (e.g. for i < myname.length() type stuff) it's just an old C habit - and shorter to type as mentioned above. However, in some cases, when interfacing to hardware where I'm dealing with event flags from devices, the uint is important in cases where a flag may use the left (highest) most bit.
Honestly, for 99.9% of my work I could easily use ushort, but int, you know, sounds sounds a lot better than ushort.
I have made a Direct3D 10 wrapper in C# & need to use uint if I want to create very large vertex buffers. Large buffers in the video card can not be represented with a signed int.
UINT is very useful & is silly to say otherwise. If anyone thinks just because they have never needed to use uint no one else will, you are wrong.
I think it is just laziness. C# is inherently a choice for development on desktops and other machines with relatively much resources.
C and C++, however, has deep roots in old systems and embedded systems where memory is sparse, so programmers are used to think carefully what datatype to use.
C# programmers are lazy, and since there are enough resources in general, nobody really optimizes memory usage (in general, not always of course). Event if a byte would be sufficient, a lot of C# programmers, including me, just use int for simplicity. Moreover, a lot of API functions accept ints, so it prevents casting.
I agree that choosing the correct datatype is good practice, but I think the main motivation is laziness.
Finally, choosing an integer is more mathematically correct. Unsigned ints don't exist in math (only natural numbers). And since most programmers have a mathematical background, using an integer is more natural.
I think a big part of the reason is that when C first came out most of the examples used int for brevity's sake. We rejoiced at not having to write integer like we did with Fortran and Pascal, and in those days we routinely used them for mundane things like array indices and loop counters. Unsigned integers were special cases for large numbers that needed that last extra bit. I think it's a natural progression that C habits continued into C# and other new languages like Python.
Some languages (e.g. many versions of Pascal) regard unsigned types as representing numeric quantities; an operation between an unsigned type and a signed type of the same size will generally be performed as though the operands were promoted to the next larger type (in some such languages, the largest type has no unsigned equivalent, so such promotion will always be possible).
Other languages (e.g. C) regard N-bit unsigned types as a group which wraps around modulo 2^N. Note that subtracting N from a member of such a group doesn't represent numerical subtraction, but rather yields the group member which, when N is added to it, would yield the original. Arguably, certain operations involving mixtures of signed and unsigned values don't really make sense and should perhaps have been forbidden, but even code which is sloppy with its specifications of things like numeric literals will usually work, and code has been written which mixes signed and unsigned types and, despite being sloppy, does work, that the spec isn't apt to change any time soon.
It's a lot easier to work exclusively with signed types than to work out all the intricacies of interactions between signed and unsigned types. Unsigned types are useful when decomposing large numbers out of smaller pieces (e.g. for serialization) or for reconstituting such numbers, but in general it's better to simply use signed numbers for things that actually represent quantities
I know this is probably an old thread but I wanted to give some clarification.
Lets take an int8 you can store –128 to 127 and it uses 1 byte that is a total of 127 positive numbers.
When you use an int8 one of the bits is used for the negative numbers -128.
When you use a Uint8 you give the negative numbers to the positive so this allows you to use 255 positive numbers with the same amount of storage 1 byte.
The only draw back is the you have now lost the capability to use negative values.
Another problem with this is not all programming languages and databases support this.
The only reason you would use this in my opinion is when you need to be efficient in like gaming programming and you have to store large non negative numbers.
This is why not many programs use this it.
The main reason is storage is not a problem and you can't use it flexibly with other software, plugins, Database, or Api's. Also for example a bank would need negative numbers to store money etc.
I hope this will help someone.

Should I use int or UInt16?

This may be somewhat trivial, but in C# do you prefer int or UInt16 when storing a network port in a variable? Framework classes use int when dealing with a network port although UInt16 actually represents the valid values.
signed (int / short etc, rather that uint / ushort) have the advantage of being CLS compliant, so that is recommended unless you have a good reason.
Re int vs short - in most cases it is more efficient to compute with int (or uint), since all the operators are optimised for this. If you are only storing and retrieving it then this isn't an issue, of course.
if you have 32 bit processor and you will use 16bit value (for memory economy) it will be aligned to 32bit. So I think it is not so important use 16bit uint instead of 32bit value.

C# Network encoding

I'm working on a networking application in C#, sending a lot of plain numbers across the network. I discovered the IPAddress.HostToNetworkOrder and IPAddress.NetworkToHostOrder methods, which are very useful, but they left me with a few questions:
I know I need to encode and decode integers, what about unsigned ones? I think yes, so at the moment I'm doing it by casting a pointer to the unsigned int into a pointer to an int, and then doing a network conversion for the int (since there is no method overload that takes unsigned ints)
public static UInt64 HostToNetworkOrder(UInt64 i)
{
Int64 a = *((Int64*)&i);
a = IPAddress.HostToNetworkOrder(a);
return *((UInt64*)&a);
}
public static UInt64 NetworkToHostOrder(UInt64 a)
{
Int64 i = *((Int64*)&a);
i = IPAddress.HostToNetworkOrder(i);
return *((UInt64*)&i);
}
2. What about floating point numbers (single and double). I think no, however If I do need to should I do a similar method to the unsigned ints and cast a single pointer into a int pointer and convert like so?
EDIT:: Jons answer doesn't answer the second half of the question (it doesn't really answer the first either!), I would appreciate someone answering part 2
I suspect you'd find it easier to use my EndianBinaryReader and EndianBinaryWriter in MiscUtil - then you can decide the endianness yourself. Alternatively, for individual values, you can use EndianBitConverter.
You'd better read several RFC documents to see how different TCP/IP protocols (application level, for example, HTTP/FTP/SNMP and so on).
This is generally speaking, a protocol specific question (both your questions), as your packet must encapsulate the integers or floating point number in a protocol defined format.
For SNMP, this is a conversion that changing an integer/float number to a few bytes and changing it back. ASN.1 is used.
http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One

Categories