Is there a way to show the representation of an int in bits in c#?
i.e.
1 = 00001
20 = 10100
etc.
I have tried using BitConverter with no luck. This should be simple, but I can't find a solution!
Convert.ToString(value, base)
Converts the value of a 32-bit signed integer to its equivalent string representation in a specified base. Specify 2 for the base.
Here's a one-liner using linq:
var myint = 20;
var bytes = Enumerable.Range(0, 32).Select(b => (myint >> b) & 1);
// { 0, 0, 1, 0, 1, 0 ... }
Of course this is in reverse order, to swap it around just use:
var myint = 20;
var bytes = Enumerable.Range(0, 32).Select(b => (myint >> (31 - b)) & 1);
// { ..., 0, 1, 0, 1, 0, 0 }
You could also look at using a BitArray.
var array = new BitArray(BitConverter.GetBytes(1));
Related
I have a code that converts BitArray values to byte[] values. I got the code also from stackoverflow.
The code is working great, I just don't understand one part.
When the codes copies the BitArray to Byte using BitArray.CopyTo() the byte reading is in LSB order.
Can someone help me understand why the converted byte is in LSB order?
strBit (is a string value that consists of 1/0)
byte[] myByte = new byte[50];
List<string> list = Enumerable.Range(0, strBit.Length / 8)
.Select(i => strBit.Substring(i * 8, 8))
.ToList();
for (int x = 0; x < list.Count; x++)
{
BitArray myBitArray = new BitArray(list[x].ToString().Select(c => c == '1').ToArray());
myBitArray.CopyTo(myByte, x);
}
Example Output:
strBit[0] = 10001111 (BitArray)
when converted to Byte:
myByte[0] = 11110001 (Byte) (241/F1)
Because we count bits from the right and items from the left; for instance for
BitArray myBitArray = new BitArray(new byte[] { 10 });
We have for the byte 10 (counting from the right):
10 = 00001010 (binary)
^
second bit (which is 1)
when items of the corresponding array we count from the left:
{false, true, false, true, false, false, false, false}
^
corresponding second BitArray item (which is true)
That's why if we want to have an array of byte back we have to Reverse each byte representation, e.g. Linq solution
using System.Collections;
using System.Linq;
...
BitArray myBitArray = ...
byte[] myByte = myBitArray
.OfType<bool>()
.Select((value, index) => new { // into chunks of size 8
value,
chunk = index / 8 })
.GroupBy(item => item.chunk, item => item.value)
.Select(chunk => chunk // Each byte representation
.Reverse() // should be reversed
.Aggregate(0, (s, bit) => (s << 1) | (bit ? 1 : 0)))
.Select(item => (byte) item)
.ToArray();
If I have a list of both positive and negative integers:
var values = new List<int> { -30, -20, -10, 0, 10, 20, 30 };
How do I convert all the values to positive numbers?
var values = new List<int> { 30, 20, 10, 0, 10, 20, 30 };
I know I could use intValue = intValue * -1 but that would only convert the negatives to positives and vice versa. Besides, if possible I would like to do this using LINQ.
Use Math.Abs:
var positives = values.Select(i => Math.Abs(i)).ToList();
Or the shortened form using method group syntax (as mentioned by #CommuSoft in the comments):
var positives = values.Select(Math.Abs).ToList();
values.Select(Math.Abs).ToList();
Or
values.Select(n => n < 0 ? -n : n).ToList();
Or (fastest way)
values.Select(n => n & int.MaxValue).ToList();
I've done some extensive searching for this so if this is a duplicate please slaughter me :D
I have a List of byte arrays (List) where the arrays are of varying length. I need to sort the list by the array lengths in ascending order then by the bytes in the array (please see example).
Example:
I want to go from:
{0,1,2}
{0,4}
{0,3,2}
{0,1,3}
{0,2,4,6,1}
{0,1,1}
{0,3,4,5}
to:
{0,4}
{0,1,1}
{0,1,2}
{0,1,3}
{0,3,2}
{0,3,4,5}
{0,2,4,6,1}
It's essentially alphabetical order but with a set of numbers instead of characters (arguably the same thing), any ideas?
The only thing you need to do is implement a IComparer<T> interface and provide that to the sorting algorithm. In this case the algorithm looks like:
public ByteArrayComparer : IComparer<byte[]> {
public int Compare (byte[] ba, byte[] bb) {
int n = ba.Length; //fetch the length of the first array
int ci = n.CompareTo(bb.Length); //compare to the second
if(ci != 0) { //if not equal return the compare result
return ci;
} else { //else elementwise comparer
for(int i = 0; i < n; i++) {
if(ba[i] != bb[i]) { //if not equal element, return compare result
return ba[i].CompareTo(bb[i]);
}
}
return 0; //if all equal, return 0
}
}
}
Next you can use the List<T>.Sort method:
List<byte[]> data = new List<byte[]>();
//add arrays to data
data.Sort(new ByteArrayComparer());
//data is now sorted
The sorting algorithm requires that the comparator is valid, a comparator is valid if it satisfies the three constraints on an ordering relation:
Reflexivity: if an elements is compared with itself, return 0;
Anti-symmetric: If x is smaller than y (return something less than 0), then y is greater than x (something greater than 0);
Transitive: if x is smaller than y and y is smaller than z, then x is smaller than z.
If the comparer doesn't satisfy that relation, the sorting algorithm will fail to sort correctly, simply because your order makes no sense.
Why not simply use LINQ
MyList = MyList.OrderBy(arr=>arr.Length).ThenBy(arr =>arr.Sum()).ToList();
A working example :
List<int[]> a = new List<int[]>();
int[] t1 = { 0, 4 };
int[] t2 = { 0, 1, 2 };
int[] t3 = { 0, 1, 3 };
int[] t4 = { 0, 2, 4, 6, 1 };
int[] t5 = { 0, 1, 1 };
int[] t6 = { 0, 3, 4, 5 };
a.Add(t1);
a.Add(t2);
a.Add(t3);
a.Add(t4);
a.Add(t5);
a.Add(t6);
a = a.OrderBy(arr=>arr.Length).ThenBy(arr =>arr.Sum()).ToList();
foreach (int[] item in a)
{
foreach (int item2 in item)
{
Console.Write(" "+item2);
}
Console.WriteLine();
}
Sample output :
0 4
0 1
0 1 2
0 1 3
0 3 4 5
0 2 4 6 1
And as pointed out this could fail in scenarios like {3 4 5} , {4 5 3}
I have a decimal value of 126 which is converted to binary value using the below code:
binary[i] = Convert.ToString(bmparrayelement[i], 2);
then I got the value as "111 1110" which is right.
Then I want to append zeros along with this value in prefix that is "00 0111 1110"
Try something like this:-
string s1 = Convert.ToString(byteArray[20], 2).PadLeft(10, '0');
Sorry if I have misunderstood but why can't you just do the below?
binary[i] = "00 0" + Convert.ToString(bmparrayelement[i], 2);
Try this:
var binary = new byte[] {1, 1, 1, 1, 1, 1, 0};
var zeroed = new byte[] {0, 0};
binary = zeroed.Concat(binary).ToArray();
Update
In .net 2.0 you can use:
const int number = 2;
var binary = new byte[] {1, 1, 1, 1, 1, 1, 0};
var a = new byte[binary.Length + number];
binary.CopyTo(a, number);
binary = a;
If Start=0 and Count=10 then how to get the alternate values using Enumerable.Range()
the out put should be like { 0, 2, 4, 6, 8 }
and if Start=1 and Count=10 then { 1, 3, 5, 7, 9 }
The continuous value can be get like
var a = Enumerable.Range(0,10).ToList();
but how to get the alternate values?
Halving the number of items that Range should generate (its second parameter) and then doubling the resulting values will give both the correct number of items and ensure an increment of 2.
Enumerable.Range(0,5).Select(x => x * 2)
Enumerable.Range(0, 10).Where(i => i % 2 == 0); // { 0, 2, 4, 6, 8 }
Enumerable.Range(0, 10).Where(i => i % 2 != 0); // { 1, 3, 5, 7, 9 }
The count parameter in your code looks like an end point of the loop.
public static MyExt
{
public static IEnumerable<int> Range(int start, int end, Func<int, int> step)
{
//check parameters
while (start <= end)
{
yield return start;
start = step(start);
}
}
}
Usage: MyExt.Range(1, 10, x => x + 2) returns numbers between 1 to 10 with step 2
MyExt.Range(2, 1000, x => x * 2) returns numbers between 2 to 1000 with multiply 2 each time.
What you are after here does not exist in the BCL as far as I'm aware of, so you have to create your own static class like this to achieve the required functionality:
public static class MyEnumerable {
public static IEnumerable<int> AlternateRange(int start, int count) {
for (int i = start; i < start + count; i += 2) {
yield return i;
}
}
}
Then you can use it like this wherever you want to:
foreach (int i in MyEnumerable.AlternateRange(0, 10)) {
//your logic here
}
You can then also perform LINQ queries using this since it returns IEnumerable
So if you want you can also write the above like this if you want to exclude the number 6
foreach (int i in MyEnumerable.AlternateRange(0, 10).Where( j => j != 6)) {
//your logic here
}
I hope this is what you are after.
You can't have this as an extension method on the Enumerable class directly since that is a static class, and extension methods work on an object of a class, and not the class itself. That's why you have to create a new static class to hold this method if you want to mimic the Enumerable class.
This can be done more simply using Linq and by specifying the minimum, length, and step values:
Enumerable.Range(min, length).Where(i => (i - min) % step == 0);
Usage with 0 through 10 at a step size of 2:
var result = Enumerable.Range(0, 10).Where(i => (i - 10) % 2 == 0);
Output:
0, 2, 4, 6, 8
Usage with 1 through 10 at a step size of 2:
var result = Enumerable.Range(1, 10).Where(i => (i - 10) % 2 == 0);
Output:
1, 3, 5, 7, 9
You could go further and make a simple function to output it using a minimum, maximum, and step value:
public static IEnumerable<int> RangedEnumeration(int min, int max, int step)
{
return Enumerable.Range(min, max - min + 1).Where(i => (i - min) % step == 0);
}
The reason to set the range length to max - min + 1 is to ensure the max value is inclusive. If the max should be exclusive, remove the + 1.
Usage:
var Result = RangedEnumeration(0, 10, 2); // 0, 2, 4, 6, 8, 10
var Result = RangedEnumeration(1, 10, 2); // 1, 3, 5, 7, 9
var Result = RangedEnumeration(1000, 1500, 150); // 1000, 1150, 1300, 1450