2

I'm looking to convert this line of C code to C#:

const u64 a = 1, b = -a;

So my understanding is that both constants are unsigned 64-bit integers. If so, what is the result going to look like?

Or is the second constant actually promoted and therefore defined as a signed integer?

HTTP 410
  • 17,300
  • 12
  • 76
  • 127

4 Answers4

4

This would be the equivalent C#:

const ulong a = 1, b = unchecked((ulong)-1);

Or more simply:

const ulong a = 1, b = 18446744073709551615;
ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
3

The C# compiler will try to protect you from accidentally negiting an unsigned integer, but you can force it like this:

ulong a = 1;
ulong b = (ulong)-(long)a;

The result will be exactly the same bunch of bits as when negating a signed integer (i.e. two's complement), the only difference is how these bits are interpreted.

Branko Dimitrijevic
  • 50,809
  • 10
  • 93
  • 167
1

Due to the behaviour of negating unsigned integers, the representation of -(u64)1 is all 1s. So, after the following:

const u64 a = 1, b = -a;

// a is now 0x0000000000000001
// b is now 0xffffffffffffffff

Of course, 0xffffffffffffffff is also (2^64) -1, which is 18446744073709551615.

In my opinion, it would have been clearer for the original programmer to instead write:

const u64 a = 1, b = ~(u64)0;

I'm not a C# programmer, but I suspect the following will work for you:

const ulong b = ~(ulong)0;
Community
  • 1
  • 1
Timothy Jones
  • 21,495
  • 6
  • 60
  • 90
  • I think `~0` depends on the same undefined behavior as `-1` (casting `int` to `uint64`). `~(u64)0` should solve this. – Piotr Praszmo Feb 08 '12 at 02:48
  • It's not UD in C. The standard clearly defines the result of conversion of signed negative integers to unsigned integers. But we don't even have that here. `1` is signed positive that is converted to unsigned (to type of `a`) without change. `a` is unsigned because it's defined as unsigned. And so is `-a`. See [this question and answers to it](http://stackoverflow.com/q/8026694/968261) – Alexey Frunze Feb 08 '12 at 02:57
  • @Alex Thanks, I'll remove the answer shortly. Can you tell me where the C standard defines the result of conversion from signed negative to unsigned? If I'm reading it correctly, in your question you say it doesn't? – Timothy Jones Feb 08 '12 at 03:09
  • @Alex: Updated answer to remove the comments about UB. Thanks for the feedback! – Timothy Jones Feb 08 '12 at 03:22
0

You get an ambiguous invocation error because -1 is not possible as an unsigned type (see comment below). You would have to use Int64 as type (which equals long).

When using long as type then the result will be a = 1, b = -1 and both longs.

Michel Keijzers
  • 15,025
  • 28
  • 93
  • 119
  • How can b be -1 if it's unsigned? Sorry, can't check at home as I only have the C# version of Visual Studio Express. – HTTP 410 Feb 08 '12 at 02:27
  • If that's about C, there's no error here, even though mathematically -1 cannot be non-negative. The only error can be that the programmer doesn't know what's he doing. – Alexey Frunze Feb 08 '12 at 03:03