How to convert an integer to binary stored in array - c#

I know how to convert an integer from decimal to fixed length binary string:
int number = 3;
int toBase = 2;
int length = 8;
Convert.ToString(number, toBase).PadLeft(length, '0')
Output:
00000011
How to assign the individual elements of that binary string to either int (or bool) array, such that after the conversion the array will look like1:
int[] binary = {0, 0, 0, 0, 0, 0, 1, 1}
or
bool[] binary = {false, false, false, false, false, false, true, true};
1. Using the facilities and not trivial for loop with char to int (or bool) type conversions.

You can add some Linq to represent the string as an array:
string source = Convert.ToString(number, toBase).PadLeft(length, '0');
...
int[] binary = source.Select(c => c - '0').ToArray();
...
bool[] binary = source.Select(c => c == '1').ToArray();
Or you can compute arrays directly:
int[] binary = Enumerable
.Range(1, length)
.Select(i => number / (1 << (length - i)) % 2)
.ToArray();
bool[] binary = Enumerable
.Range(1, length)
.Select(i => number / (1 << (length - i)) % 2 == 1)
.ToArray();

If you store the string you have created, for example
string theBinaryString = Convert.ToString(number, toBase).PadLeft(length, '0');
int[] binary = new int[8];
for(int i = 0; i < 8; i++)
{
binary[i] = int.parse(theBinaryString[i].ToString());
}
Once the loop has finished you will have the array you are looking for, the ToString() is required as selecting from a string as if it was an array returns a char, which cannot be parsed into an int.

You can do it without converting the number to binary string:
var num = 123;
var bits = Enumerable.Range(0, 8).Select(i => (num >> (7-i)) & 1).ToArray();
The idea is to shift the number right sequentially by a decreasing number of positions, and mask off all bits except least significant one.
Demo.

maybe like this;
"1000110101110".ToCharArray().Select(c => c - '0').ToArray()
will give you:
int[13] { 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0 }

int[] intArray = stringNumber.ToCharArray().Select(n => Convert.ToInt32(n)).ToArray();

Related

Convert decimal integers into 4-bit binary

I want to convert decimal integers taken from an array and convert into 4-bit binary and store each of the bit into array in c#
static void Main()
{
BinaryInput a = new BinaryInput();
int[] input = { 7, 0, 0, 0, 2, 0, 4, 4, 0 };
int x;
int[] bits = new int[36];
ArrayList Actor = new ArrayList();
for (int i = 0; i < input.Length; i++)
{
x = (int)input[i];
string result = Convert.ToString(x, 2);
bits = result.PadLeft(4, '0').Select(c =>int.Parse(c.ToString())).ToArray();
Actor.Add(bits);
}
}
The ArrayList Actor consists of 9 arrays and each array consist of binary number......but i want to add each of the binary bit in a single array as an individual element of the array or arraylist {0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0}
You can write a method to get the "bits" of a number like this
private static IEnumerable<int> ToBitSequence(this int num, int size)
{
while (size > 0)
{
yield return num & 1;
size--;
num >>= 1;
}
}
Then you can use it in the following way to get your desired results.
int[] input = { 7, 0, 0, 0, 2, 0, 4, 4, 0 };
var bits = input.Reverse().SelectMany(i => i.ToBitSequence(4)).Reverse();
Console.WriteLine(string.Join(",", bits));
Results in
0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0
The reason for the two Reverse calls is because ToBitSequence will return the least significant bit first, so by feeding the number in reverse order and then reversing the results you will get the bits from most significant to least starting with the first number in your list.
This is preferable to all the parsing and formatting between char, string, and int that you're currently doing.
However if you just change Actor to List<int> and do Actor.AddRange(bits); that would also work.
Use BitArray
BitArray b = new BitArray(new byte[] { x });
int[] bits = b.Cast<bool>().Select(bit => bit ? 1 : 0).ToArray();
This will give you the bits, then use
bits.Take(4).Reverse()
to get the least significant 4 bits in most-significant order first for each number.

How can I convert a base 10 (decimal) string to an array of bytes _directly_ in C#?

I'm looking to take a variable length string input, interpret it numerically, and parse it into a byte array, while imposing no limitations on its length.
I have binary and hex done:
public static byte[] GetHexBytes(this string hex, bool preTrimmed = false)
{
if (!preTrimmed)
{
hex = hex.Trim();
if (hex.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
hex = hex.Substring(2);
else if (hex.StartsWith("16#"))
hex = hex.Substring(3);
}
if (hex.Length % 2 != 0) hex = hex.PadLeft(hex.Length + 1, '0');
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
public static byte[] GetBinaryBytes(this string binary, bool preTrimmed = false)
{
if (!preTrimmed)
{
binary = binary.Trim();
if (binary.StartsWith("0b", StringComparison.OrdinalIgnoreCase) || binary.StartsWith("2#"))
binary = binary.Substring(2);
}
if (binary.Length % 8 != 0) binary = binary.PadLeft(binary.Length + 8 - binary.Length % 8, '0');
return Enumerable.Range(0, binary.Length)
.Where(x => x % 8 == 0)
.Select(x => Convert.ToByte(binary.Substring(x, 8), 2))
.ToArray();
}
public static byte[] GetDecimalBytes(this string dec, bool preTrimmed = false)
{
if (!preTrimmed)
{
dec = dec.Trim();
if (dec.StartsWith("10#"))
dec = dec.Substring(3);
}
//???
}
Is it possible to do this conversion in a forward manner, similar to the hex and binary versions (start at the beginning of the string, working forward)?
If not, can it be done working in reverse in such a way that doesn't impose any limitations on the length of the string, without using something like System.Numerics or BigInteger (doing it manually, from the string)?
I'd like it to handle any string length, up to the maximum string length of C# (1,073,741,823).
Examples
"FF".GetHexBytes() => [ 0xFF ]
"11111111".GetBinaryBytes() => [ 0xFF ]
"255".GetDecimalBytes() => [ 0xFF ]
"FFFF".GetHexBytes() => [ 0xFF, 0xFF ]
"1111111111111111".GetBinaryBytes() => [ 0xFF, 0xFF ]
"65535".GetDecimalBytes() => [ 0xFF, 0xFF ]
I just couldn't resist building a somewhat working solution to this question. However, as I already commented, calling the approach directly is a bit of an overstatement and the presented code is neigher input-validating nor efficient.
My basic approach is as follow:
Convert each digit to a list of zero based bit indices, associated with the index position of the digit
Transform the bit index list according to the digit position
Used approach: value * 10 == value * (8 + 2) == (value << 3) + (value << 1)
Summarize bit indices by eliminating two equal index values and adding their successor value (bitwise addition)
Theoretically it would be enough to apply bit addition once at the end, but in reality, intermediate compression is needed to avoid out of memory exceptions for large numbers
// example input
string input = "6524562164126412641206685";
var result = input
// interpret the string as a list of digits with position
.Reverse()
// transfer from list of positioned digits to list of actual bit positions,
// by repeatedly multiplying with 10
// the resulting bits need to be added for the final result
.SelectMany((x, i) =>
{
// digit value
var val1 = x - '0';
var res1 = new List<int>();
// to bit positions, as if it was the first digit
for (int j = 0; j < 8; j++)
{
if ((val1 & (1 << j)) != 0) res1.Add(j);
}
// to absolute bit positions, taking the digit position into account
for (int j = 1; j <= i; j++)
{
var res = new List<int>();
// multiply by 10, until actual position is reached
foreach (var item in res1)
{
res.Add(item + 1);
res.Add(item + 3);
}
// compress bits
res1 = res.Aggregate(new HashSet<int>(), (set, i1) =>
{
// two bits in the same position add up to one bit in a higher position
while (set.Contains(i1))
{
set.Remove(i1);
i1++;
}
set.Add(i1);
return set;
}).ToList();
}
return res1;
}).
// final elimination of duplicate bit indices
Aggregate(new HashSet<int>(), (set, i) =>
{
while (set.Contains(i))
{
set.Remove(i);
i++;
}
set.Add(i);
return set;
})
// transfer bit positions into a byte array - lowest bit is the last bit of the first byte
.Aggregate(new byte[(long)Math.Ceiling(input.Length / 2.0)], (res, bitpos) =>
{
res[bitpos / 8] |= (byte)(1 << (bitpos % 8));
return res;
});
Actually splitting the actions into separate functions would be recommended instead of this huge linq blob ;)
5 years late but maybe this might help someone else:
public static byte[] GetHexBytes(this string hex)
{
return BigInteger.Parse(hex, System.Globalization.NumberStyles.HexNumber).ToByteArray(true);
}
public static byte[] GetDecimalBytes(this string dec)
{
return BigInteger.Parse(dec).ToByteArray(true);
}
// Example:
using System.Numerics;
byte[] inHex = "FFFF".GetHexBytes(); // => [ 0xFF, 0xFF ]
byte[] inDec = "65535".GetDecimalBytes(); // => [ 0xFF, 0xFF ]

Re sizing array [duplicate]

This question already has answers here:
Deleting A Specified Element In An Array Using Random Class
(4 answers)
Closed 9 years ago.
int oldLength = numbers.Length;
int[] arrTmp = numbers;
numbers = new int[oldLength - 1];
Array.Copy(arrTmp, numbers, Token);
Array.Copy(arrTmp, r+1, numbers, Token, oldLength - Token - 1);
This all i got to remove a specified element from a value type array but it doesn't work.
I got 4 elements of value type array. I have stored 4 different numbers in it.
array[0] = 2;
array[1] = 4;
array[2] = 6;
array[3] = 8;
i got a random class to randomly pick a number if it is 2 has to be removed from my array in an ascending sequential order each element should be inspected and eliminated.
You would do much easier using the List class
List<int> l = new List<int>();
l.Add(2);
l.Add(4);
...
l.Remove(2);
int oldLength = numbers.Length;
int[] arrTmp = new int[oldLength - 1];
for(int i = 0, j = 0; i < oldLength || j < arrTmp.Length; i++)
{
if(numbers[i] == Token)
continue;
arrTmp[j++] = numbers[i];
}
using linq:
var newArray = numbers.Where(n=> n!= Token).ToArray();
This would be the general approach:
int oldLength = numbers.Length;
int[] arrTmp = numbers;
numbers = new int[oldLength - 1];
Array.Copy(arrTmp, numbers, r);
Array.Copy(arrTmp, r + 1, numbers, r, oldLength - r - 1);
Note the use of r everywhere. Here r would be the index of the element to omit.
If you really need to use plain arrays and copy their contents using Array.Copy (which is not a common way of handling things in .NET), then start by using a pen and write down correct indices and lengths of the array parts you are trying to copy.
Starting to code the solution before you know how to solve it won't get you far.
So, start with an example array and a random index:
// starting array
int[] array = { 0, 1, 2, 3, 4, 5, 6, 7 };
// index to remove
int indexToRemove = new Random().Next(array.Length);
Now, presume that indexToRemove is 3 and try to do it by hand:
Part 1: { 0, 1, 2 } (start = 0, length = 3)
Part 2: { 4, 5, 6, 7 } (start = 4, length = 4)
From this concrete example, you can try to infer the general formula for offset and length of these two array parts:
Part 1: start = 0, length = (indexToRemove - 1)
Part 2: start = (indexToRemove + 1), length = (array.Length - indexToRemove - 1)
The code itself is then trivial:
var len = array.Length;
var newArray = new int[len - 1];
Array.Copy(array, 0, newArray, 0, indexToRemove - 1);
Array.Copy(array, indexToRemove + 1, newArray, indexToRemove, len - indexToRemove - 1);
Additionally, the Array.Copy can be used to copy a part of an array over itself, which means you can just move the second part of the array back by one position, and then resize the initial array using Array.Resize:
// do not create a new array, but simply "move" the 2nd part to left
Array.Copy(array, indexToRemove + 1, array, indexToRemove, len - indexToRemove - 1);
// finally, resize the original array
Array.Resize(ref array, array.Length - 1);
Of course, if you simply used a List<int>, then you would simply use the List<T>.RemoveAt method to remove the item:
var list = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
int indexToRemove = new Random().Next(list.Count);
list.RemoveAt(indexToRemove);

Find all subsets with Enumerable.Zip or bitwise AND logic

I wanted to find all subsets of an array of integers, so my first thought was to use the binary representation of numbers of size n bits, where 1 includes and 0 doesn't include.
For example:
int[] arr = { 3, 4, 5 };
going through numbers 0 to 7 gives me:
0,0,0
0,0,1
0,1,0
0,1,1
1,0,0
...etc
this maps to:
empty
5
4
4,5
3
...etc
To do the mapping I used Enumerable.Zip. The code is:
public static IEnumerable<byte> ToBinary(this int value, int size)
{
return ToBinaryStream(value, size).Reverse();
}
private static IEnumerable<byte> ToBinaryStream(int value, int size)
{
if (value < 0)
yield break;
do
{
yield return (byte)(value & 1);
--size;
}
while ((value = value >> 1) > 0 || size > 0);
}
int?[] arr = { 1,2,3,4 };
List<int[]> subsets = new List<int[]>();
for (int i = 0; i < (int)Math.Pow(2, (arr.Length)); i++)
{
var subset = i.ToBinary(arr.Length).Zip(arr, (value, array) => value == 1 ? array : null)
.Where(a => a != null).Cast<int>().ToArray();
subsets.Add(subset);
}
Seems to work great. Question is how can I use bitwise AND logic to do the same thing?
I want to map 1000 to the first element in the array, and 1001 to the first and last etc.
To check if an element x with index i should be included for a number num:
Shift 1 left by i
Bitwise AND the result with num
If the result is greater than 0, include x
Here's the code:
int[] arr = { 1,2,3,4 };
List<int[]> subsets = Enumerable
.Range(0, (int)Math.Pow(2, (arr.Length)))
.Select(num => arr.Where((x, i) => ((1 << i) & num) > 0).ToArray())
.ToList();
It treats the lowest bit in num as the first element in the array to avoid having to reverse things. Interesting idea by the way :)

need a better way add leading digits to int and return array of digits

I need to create a modulus check which adds leading digits, lets say 0, to a seed int. I then need to return an array of digits in the array as I need to do a calculation on each digit to return a new whole number.
my code is as follows,
var seed = 1234;
var seedString = seed.ToString();
var test = new List<int>();
for(int i = 0; i < 10 - seedString.Length; i++)
{
test.Add(0);
}
var value = seed;
for(int i = 0; i < seedString.Length; i ++)
{
test.Insert(10 - seedString.Length, value % 10);
value = value / 10;
}
is there an easier way of doing this?
If you want to convert your number to a 10-digit string, you can format the number using a Custom Numeric Format String as follows:
string result = seed.ToString("0000000000");
// result == "0000001234"
See: The "0" Custom Specifier
If you need a 10-element array consisting of the individual digits, try this:
int[] result = new int[10];
for (int value = seed, i = result.Length; value != 0; value /= 10)
{
result[--i] = value % 10;
}
// result == new int[] { 0, 0, 0, 0, 0, 0, 1, 2, 3, 4 }
See also: Fastest way to separate the digits of an int into an array in .NET?
Try this:
int myNumber = 1234;
string myStringNumber = myNumber.ToString().PadLeft(10, '0');
HTH
Another shorthand way of getting the string representation would be
int num = 1234;
num.ToString("D10");

Categories

Resources