binary number represented in a long variable in c# - c#

In code I am having a problem I would like to see in the enumerator class a binary format. You know in c# we have the possibility to represent Hexadecimal with 0xFF (f.e.). I would like to know if we have something similar for binary number like:
public static class MyEnum
{
public static const long TR = 000000001;
public static const long TRP = 000000010;
...
}
This enumerator represent 1, 2, 4, 8, ... for any type I put inside. Just I need a binary number to see easy the number.
How can I represent binary in C#?

I dont think there is any such representation in C#
From the ECMA script
9.4.4.2 Integer literals Integer literals are used to write values of types int, uint, long, and ulong. Integer literals have two possible
forms: decimal and hexadecimal.
Also check .NET Compiler Platform ("Roslyn")
Probably C# 6.0 will add that feature
C# now tries to help us by introducing a binary literal. Let's start with what we currently have:
var num1 = 1234; //1234
var num2 = 0x1234; //4660
What could possible come now? Here's the answer:
var num3 = 0b1010; //10
Of course binary digits are becoming quite long very fast. This is why a nice separator has been introduced:
var num4 = 0b1100_1010; //202
There can be as many underscores as possible. The underscores can also be connected. And the best thing: Underscores do also work for normal numbers and hex literals:
var num5 = 1_234_567_890; //123456789
var num6 = 0xFF_FA_88_BC; //4294609084
var num7 = 0b10_01__01_10; //150
The only constraint of the underscore is, that of course a number cannot start with it.
Binary literals will make enumerations and bit vectors a little bit easier to understand and handle. It is just more close at what we have been thinking when creating such constructs.

If you plan to use only powers of two, the idiomatic way of doing it is by using shifts:
public static const long TR = 1L << 0;
public static const long TRP = 1L << 1;
The L suffix becomes necessary when you shift left by 32 or more positions.
Link: C# does not provide a syntax for binary literals.

You can't. Not yet anyway. It will be introduced in C# 6.
The syntax will be similar to hexadecimal:
int i = 0b1110000101;
Another great feature that complements this is that you can use underscores in numbers:
int i = 0b11_1000_0101;

I'm not sure if I would ever really do this, but here's an idea that just came to me:
const byte b0001 = 0x1;
const byte b0010 = 0x2;
const byte b0100 = 0x4;
const byte b1000 = 0x8;
const long Value1 = (// 0b0111
b0001 |
b0010 |
b0100);
const long Value2 = (// 0b01100111
b0010 |
b0100)
<< 4 | (
b0001 |
b0010 |
b0100);
Or you could do something this, which is the same idea but a bit more readable:
const byte b0110 = 0x6;
const byte b0111 = 0x7;
const long Value3 = b0110 << 4 | b0111;

Related

Unsigned shift right in C# Using Java semantics for negative numbers

I'm trying to port Java code to C# and I'm running into odd bugs related to the unsigned shift right operator >>> normally the code:
long l = (long) ((ulong) number) >> 2;
Would be the equivalent of Java's:
long l = number >>> 2;
However for the case of -2147483648L which you might recognized as Integer.MIN_VALUE this returns a different number than it would in Java since the cast to ulong changes the semantics of the number hence I get a different result.
How would something like this be possible in C#?
I'd like to preserve the code semantics as much as possible since its a pretty complex body of code.
I believe your expression is incorrect when considering C#'s order precedence. Your code I believe is converting your long to ulong, then back to long, then shifting. I'm assuming your intent was to perform the shift on the ulong.
From the C# Specification ยง7.2.1, Unary (or in your case, the casting operation) takes precedence over the shifting. Thus your code:
long l = (long) ((ulong) number) >> 2;
would be interpreted as:
ulong ulongNumber = (ulong)number;
long longNumber = (long)ulongNumber;
long shiftedlongNumber = longNumber >> 2;
Given number as -2147483648L, this yields 536870912.
By wrapping the conversion and shifting in parenthesis:
long l = (long) (((ulong) number) >> 2);
Produces logic that could be rewritten as:
ulong ulongNumber = (ulong)number;
ulong shiftedulongNumber = ulongNumber >> 2;
long longShiftedNumber = (long)shiftedulongNumber;
Which given number as -2147483648L, this yields 4611686017890516992.
EDIT: Note that given those ordering rules, there's an extra set of parenthesis in my answer that aren't necessary. The correct expression could be written as:
long l = (long) ((ulong) number >> 2);

Binary notation for writing bits - C#

There are some notations to write numbers in C# that tell if what you wrote is float, double, integer and so on.
So I would like to write a binary number, how do I do that?
Say I have a byte:
byte Number = 10011000 //(8 bits)
How should I write it without having the trouble to know that 10011000 in binary = 152 in decimal?
P.S.: Parsing a string is completely out of question (I need performance)
as of c# 6 c# 7 you can use 0b prefix to get binary similar to the 0x for hex
int x = 0b1010000; //binary value of 80
int seventyFive = 0b1001011; //binary value of 75
give it a shot
You can write this:
int binaryNotation = 0b_1001_1000;
In C# 7.0 and later, you can use the underscore '_' as a digit seperator including decimal, binary, or hexadecimal notation, to improve legibility.
There's no way to do it other than parsing a string, I'm afraid:
byte number = (byte) Convert.ToInt32("10011000", 2);
Unfortunately you will be unable to assign constant values like that, of course.
If you find yourself doing that a lot, I guess you could write an extension method on string to make things more readable:
public static class StringExt
{
public static byte AsByte(this string self)
{
return (byte)Convert.ToInt32(self, 2);
}
}
Then the code would look like this:
byte number = "10011000".AsByte();
I'm not sure that would be a good idea though...
Personally, I just use hex initializers, e.g.
byte number = 0x98;

I need to write a big-endian single-precision floating point number to file in C#

I have a file format I'm trying to write to using C#. The format encodes integer-based RGB color values as a floating point. It also stores the values as big-endian. I found an example of what I'm trying to do, written in php, here: http://www.colourlovers.com/ase.phps
I can convert the endian-ness easily. I know this code is very verbose, but I'm just using it to watch the bits swap during troubleshooting.
private uint SwapEndian(uint host) {
uint ReturnValue;
uint FirstHalf;
uint LastHalf;
FirstHalf = (host & 0xFFFF0000);
FirstHalf = (FirstHalf >> 16);
LastHalf = (host & 0x0000FFFF);
LastHalf = (LastHalf << 16);
ReturnValue = (FirstHalf | LastHalf);
return ReturnValue;
}
C# won't let me perform bit-shifts on floats. Converting to an int or uint to call my SwapEndian method above loses the encoding information the file format requires.
So, how would you take a floating point number and change its endian-ness without losing the exponent data?
You could just use:
var bytes = BitConverter.GetBytes(floatVal);
And reverse the array (assuming the CPU is little-endian, which you an check), or simply just access the array in the order you need.
There is also a way to do this with unsafe code, treating the float* as a byte* so you can get the bytes in the order you want.
I'm slightly confused as to why your shifting by 16 bits rather than 8. Naw do I understand why you need RGB as a float (they are generaly 1 byte each). But anywho.
you can use a 'fake' union to treat a float as an uint
[StructLayout(LayoutKind.Explicit)]
public struct FloatIntUnion
{
[FieldOffset(0)]
public float f;
[FieldOffset(0)]
public uint i;
}
this allows you to assign the float and then provide do bitwise operations on the uint part of the 'union' then use the float again as the final value.
However I would probably just use:
var bytes = BitConverter.GetBytes (RGB);
if (BitConverter.IsLittleEndian)
Array.Reverse (bytes);
return bytes;
until performance started to become an issue (because of THIS method (read profile first)).

C# binary literals

Is there a way to write binary literals in C#, like prefixing hexadecimal with 0x? 0b doesn't work.
If not, what is an easy way to do it? Some kind of string conversion?
Update
C# 7.0 now has binary literals, which is awesome.
[Flags]
enum Days
{
None = 0,
Sunday = 0b0000001,
Monday = 0b0000010, // 2
Tuesday = 0b0000100, // 4
Wednesday = 0b0001000, // 8
Thursday = 0b0010000, // 16
Friday = 0b0100000, // etc.
Saturday = 0b1000000,
Weekend = Saturday | Sunday,
Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday
}
Original Post
Since the topic seems to have turned to declaring bit-based flag values in enums, I thought it would be worth pointing out a handy trick for this sort of thing. The left-shift operator (<<) will allow you to push a bit to a specific binary position. Combine that with the ability to declare enum values in terms of other values in the same class, and you have a very easy-to-read declarative syntax for bit flag enums.
[Flags]
enum Days
{
None = 0,
Sunday = 1,
Monday = 1 << 1, // 2
Tuesday = 1 << 2, // 4
Wednesday = 1 << 3, // 8
Thursday = 1 << 4, // 16
Friday = 1 << 5, // etc.
Saturday = 1 << 6,
Weekend = Saturday | Sunday,
Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday
}
C# 7.0 supports binary literals (and optional digit separators via underscore characters).
An example:
int myValue = 0b0010_0110_0000_0011;
You can also find more information on the Roslyn GitHub page.
Only integer and hex directly, I'm afraid (ECMA 334v4):
9.4.4.2 Integer literals Integer literals are used to write values of
types int, uint, long, and ulong.
Integer literals have two possible
forms: decimal and hexadecimal.
To parse, you can use:
int i = Convert.ToInt32("01101101", 2);
Adding to #StriplingWarrior's answer about bit flags in enums, there's an easy convention you can use in hexadecimal for counting upwards through the bit shifts. Use the sequence 1-2-4-8, move one column to the left, and repeat.
[Flags]
enum Scenery
{
Trees = 0x001, // 000000000001
Grass = 0x002, // 000000000010
Flowers = 0x004, // 000000000100
Cactus = 0x008, // 000000001000
Birds = 0x010, // 000000010000
Bushes = 0x020, // 000000100000
Shrubs = 0x040, // 000001000000
Trails = 0x080, // 000010000000
Ferns = 0x100, // 000100000000
Rocks = 0x200, // 001000000000
Animals = 0x400, // 010000000000
Moss = 0x800, // 100000000000
}
Scan down starting with the right column and notice the pattern 1-2-4-8 (shift) 1-2-4-8 (shift) ...
To answer the original question, I second #Sahuagin's suggestion to use hexadecimal literals. If you're working with binary numbers often enough for this to be a concern, it's worth your while to get the hang of hexadecimal.
If you need to see binary numbers in source code, I suggest adding comments with binary literals like I have above.
You can always create quasi-literals, constants which contain the value you are after:
const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
If you use them often then you can wrap them in a static class for re-use.
However, slightliy off-topic, if you have any semantics associated with the bits (known at compile time) I would suggest using an Enum instead:
enum Flags
{
First = 0,
Second = 1,
Third = 2,
SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
If you look at the language feature implementation status of the .NET Compiler Platform ("Roslyn") you can clearly see that in C# 6.0 this is a planned feature, so in the next release we can do it in the usual way.
string sTable="static class BinaryTable\r\n{";
string stemp = "";
for (int i = 0; i < 256; i++)
{
stemp = System.Convert.ToString(i, 2);
while(stemp.Length<8) stemp = "0" + stemp;
sTable += "\tconst char nb" + stemp + "=" + i.ToString() + ";\r\n";
}
sTable += "}";
Clipboard.Clear();
Clipboard.SetText ( sTable);
MessageBox.Show(sTable);
Using this, for 8bit binary, I use this to make a static class and it puts it into the clipboard.. Then it gets pasted into the project and added to the Using section, so anything with nb001010 is taken out of a table, at least static, but still...
I use C# for a lot of PIC graphics coding and use 0b101010 a lot in Hi-Tech C
--sample from code outpt--
static class BinaryTable
{ const char nb00000000=0;
const char nb00000001=1;
const char nb00000010=2;
const char nb00000011=3;
const char nb00000100=4;
//etc, etc, etc, etc, etc, etc, etc,
}
:-)
NEAL
Binary literal feature was not implemented in C# 6.0 & Visual Studio 2015. but on 30-March 2016 Microsoft announced the new version of Visual Studio '15' Preview with that we can use binary literals.
We can use one or more than one Underscore( _ ) character for digit separators. so the code snippet would look something like:
int x = 0b10___10_0__________________00; //binary value of 80
int SeventyFive = 0B100_________1011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
and we can use either of 0b and 0B as shown in the above code snippet.
if you do not want to use digit separator you can use it without digit separator like below code snippet
int x = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
While not possible using a Literal, maybe a BitConverter can also be a solution?
Though the string parsing solution is the most popular, I don't like it, because parsing string can be a great performance hit in some situations.
When there is needed a kind of a bitfield or binary mask, I'd rather write it like
long bitMask = 1011001;
And later
int bit5 = BitField.GetBit(bitMask, 5);
Or
bool flag5 = BitField.GetFlag(bitMask, 5);`
Where BitField class is
public static class BitField
{
public static int GetBit(int bitField, int index)
{
return (bitField / (int)Math.Pow(10, index)) % 10;
}
public static bool GetFlag(int bitField, int index)
{
return GetBit(bitField, index) == 1;
}
}
You can use 0b000001 since Visual Studio 2017 (C# 7.0)
Basically, I think the answer is NO, there is no easy way. Use decimal or hexadecimal constants - they are simple and clear. #RoyTinkers answer is also good - use a comment.
int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8; // 000000001000
The others answers here present several useful work-a rounds, but I think they aren't better then the simple answer. C# language designers probably considered a '0b' prefix unnecessary. HEX is easy to convert to binary, and most programmers are going to have to know the DEC equivalents of 0-8 anyways.
Also, when examining values in the debugger, they will be displayed has HEX or DEC.

C# little endian or big endian?

In the documentation of hardware that allows us to control it via UDP/IP,
I found the following fragment:
In this communication protocol, DWORD is a 4 bytes data, WORD is a 2 bytes data,
BYTE is a single byte data. The storage format is little endian, namely 4 bytes (32bits) data is stored as: d7-d0, d15-d8, d23-d16, d31-d24; double bytes (16bits) data is stored as: d7-d0 , d15-d8.
I am wondering how this translates to C#?
Do I have to convert stuff before sending it over?
For example, if I want to send over a 32 bit integer, or a 4 character string?
C# itself doesn't define the endianness. Whenever you convert to bytes, however, you're making a choice. The BitConverter class has an IsLittleEndian field to tell you how it will behave, but it doesn't give the choice. The same goes for BinaryReader/BinaryWriter.
My MiscUtil library has an EndianBitConverter class which allows you to define the endianness; there are similar equivalents for BinaryReader/Writer. No online usage guide I'm afraid, but they're trivial :)
(EndianBitConverter also has a piece of functionality which isn't present in the normal BitConverter, which is to do conversions in-place in a byte array.)
You can also use
IPAddress.NetworkToHostOrder(...)
For short, int or long.
Re little-endian, the short answer (to do I need to do anything) is "probably not, but it depends on your hardware". You can check with:
bool le = BitConverter.IsLittleEndian;
Depending on what this says, you might want to reverse portions of your buffers. Alternatively, Jon Skeet has specific-endian converters here (look for EndianBitConverter).
Note that itaniums (for example) are big-endian. Most Intels are little-endian.
Re the specific UDP/IP...?
You need to know about network byte order as well as CPU endian-ness.
Typically for TCP/UDP comms, you always convert data to network byte order using the htons function (and ntohs, and their related functions).
Normally network order is big-endian, but in this case (for some reason!) the comms is little endian, so those functions are not very useful. This is important as you cannot assume the UDP comms they have implemented follow any other standards, it also makes life difficult if you have a big-endian architecture as you just can't wrap everything with htons as you should :-(
However, if you're coming from an intel x86 architecture, then you're already little-endian, so just send the data without conversion.
I'm playing around with packed data in UDP Multicast and I needed something to reorder UInt16 octets since I noticed an error in packet header (Wireshark), so I made this:
private UInt16 swapOctetsUInt16(UInt16 toSwap)
{
Int32 tmp = 0;
tmp = toSwap >> 8;
tmp = tmp | ((toSwap & 0xff) << 8);
return (UInt16) tmp;
}
In case of UInt32,
private UInt32 swapOctetsUInt32(UInt32 toSwap)
{
UInt32 tmp = 0;
tmp = toSwap >> 24;
tmp = tmp | ((toSwap & 0xff0000) >> 8);
tmp = tmp | ((toSwap & 0xff00) << 8);
tmp = tmp | ((toSwap & 0xff) << 24);
return tmp;
}
This is just for testing
private void testSwap() {
UInt16 tmp1 = 0x0a0b;
UInt32 tmp2 = 0x0a0b0c0d;
SoapHexBinary shb1 = new SoapHexBinary(BitConverter.GetBytes(tmp1));
SoapHexBinary shb2 = new SoapHexBinary(BitConverter.GetBytes(swapOctetsUInt16(tmp1)));
Debug.WriteLine("{0}", shb1.ToString());
Debug.WriteLine("{0}", shb2.ToString());
SoapHexBinary shb3 = new SoapHexBinary(BitConverter.GetBytes(tmp2));
SoapHexBinary shb4 = new SoapHexBinary(BitConverter.GetBytes(swapOctetsUInt32(tmp2)));
Debug.WriteLine("{0}", shb3.ToString());
Debug.WriteLine("{0}", shb4.ToString());
}
from which output was this:
0B0A: {0}
0A0B: {0}
0D0C0B0A: {0}
0A0B0C0D: {0}
If you're parsing and performance is not critical, consider this very simple code:
private static byte[] NetworkToHostOrder (byte[] array, int offset, int length)
{
return array.Skip (offset).Take (length).Reverse ().ToArray ();
}
int foo = BitConverter.ToInt64 (NetworkToHostOrder (queue, 14, 8), 0);

Categories

Resources