How can I convert BitArray to single int? - c#

How can I convert BitArray to a single int?

private int getIntFromBitArray(BitArray bitArray)
{
if (bitArray.Length > 32)
throw new ArgumentException("Argument length shall be at most 32 bits.");
int[] array = new int[1];
bitArray.CopyTo(array, 0);
return array[0];
}

private int getIntFromBitArray(BitArray bitArray)
{
int value = 0;
for (int i = 0; i < bitArray.Count; i++)
{
if (bitArray[i])
value += Convert.ToInt16(Math.Pow(2, i));
}
return value;
}

This version:
works for up to 64 bits
doesn't rely on knowledge of BitArray implementation details
doesn't needlessly allocate memory
doesn't throw any exceptions (feel free to add a check if you expect more bits)
should be more than reasonably performant
Implementation:
public static ulong BitArrayToU64(BitArray ba)
{
var len = Math.Min(64, ba.Count);
ulong n = 0;
for (int i = 0; i < len; i++) {
if (ba.Get(i))
n |= 1UL << i;
}
return n;
}

Reffering to this post (#43935747). A value X is short tpe whic I set two bits (6 and 10) like below:
short X=1;
var result = X;
var bitsToSet = new [ ] { 5,9 };
foreach ( var bitToSet in bitsToSet )
{
result+=( short ) Math.Pow ( 2,bitToSet );
}
string binary = Convert.ToString ( result,2 );
Now I would like to read the specific all bits from Value X and put it in to an array or a bit type like bool Val1= bit1, bool Val2=bit2....
I am a newbie and I think it is pretty simple for you guyes..

Related

Reverse binary representation of int (only significant bits)

I'm trying to write a program for reversing numbers in binary. For instance, the binary representation of 13 is 1101, and reversing it gives 1011, which corresponds to number 11 right?
Here's my code:
static void Main(string[] args)
{
Console.WriteLine("Enter a Number");
int numb = int.Parse(Console.ReadLine());
int reverse = 0;
while (numb > 0)
{
int rem = numb % 10;
reverse = (reverse * 10) + rem;
numb = numb / 10;
}
Console.WriteLine("Reverse number={0}", reverse);
Console.ReadLine();
}
By this code I only get the numbers to reverse (13 -> 31)...
The input should contain a single line with an integer N, 1≤N≤1000000000 and I want my output in one line with one integer, the number I want to get by reversing the binary representation of N.
Something like that
// 13 = 1101b
int value = 13;
// 11 = 1011b
int result = Convert.ToInt32(new String(
Convert.ToString(value, 2)
.Reverse()
.ToArray()), 2);
Explanation:
Convert.ToString(value, 2) returns value in binary representation ("1101")
Reverse().ToArray() - reverse the string ('1','0','1','1') as sequence of characters and converts to array char[].
new String(...) constructs string "1011" from array of char
finally, Convert.ToInt32(..., 2) convert binary representation back to int
You can use Convert.ToString and Convert.ToInt32 methods, where 2 means binary:
int numb = int.Parse(Console.ReadLine());
var reversedString = Convert.ToString(numb, 2).ReverseString();
var result = Convert.ToInt32(reversedString, 2);
...
public static string ReverseString(this string s)
{
char[] arr = s.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
A fun excercise would be doing this without using the string conversion.
I have very little experience with bit twiddling so there is probably a faster and better way of doing this, but this seems to work:
public static IEnumerable<bool> ToBinary(this int n)
{
for (int i = 0; i < 32; i++)
{
yield return (n & (1 << i)) != 0;
}
}
public static int ToInt(this IEnumerable<bool> b)
{
var n = 0;
var counter = 0;
foreach (var i in b.Trim().Take(32))
{
n = n | (i ? 1 : 0) << counter;
counter++
}
return n;
}
private static IEnumerable<bool> Trim(this IEnumerable<bool> list)
{
bool trim = true;
foreach (var i in list)
{
if (i)
{
trim = false;
}
if (!trim)
{
yield return i;
}
}
}
And now you'd call it like this:
var reversed = n.ToBinary().Reverse().ToInt();

Interview practice on array size i.e. I can't use arraylist, linked list, or any standard list class

I've become rusty at the brain teaser questions since I have been using fancy IDEs and C#. I have a solution for this question, but my real question is How should I deal with the array size? Assuming I can't use a list. This is written in C#.
The array size could be too small, or just be a waste of memory in its current state. I left out checks for negative coins, etc. so we could just focus on the algorithm. So I want to get rid of this line: double [] minList = new double[1000];
Here's the interview question, return the minimum number of coins that sum to a value (-1 if impossible:
public static Main(string [] args) {
double[] coins = {0.01, 0.05, 0.10, 0.25};
Console.WriteLine(MinNumberOfCoinsToSum(0.24, coins));
}
public static int MinNumberOfCoinsToSum(double sum, double [] coins)
{
double [] minList = new double[1000];
minList[0] = sum;
for (int i = 1; i < minList.Length; i++)
{
double buffer = minList[i-1];
for (int j = 0; j < coins.Length; j++)
{
if(minList[i-1] - coins[j] >= 0.0)
{
buffer = Math.Min(buffer, minList[i-1] - coins[j]);
}
}
minList[i] = Math.Min(minList[i-1], Math.Round(buffer, 2));
if (minList[i] == 0.0)
{
return i;
}
}
return -1;
}
Well Here's an answer taking in what you guys said (though it doesn't return -1 if not found):
private static int MinNumberOfCoinsToSumRecursiveDecimalVersion(decimal sum, decimal [] coins)
{
decimal buffer = sum;
for(int i = 0; i < coins.Length; i++)
{
if(sum - coins[i] >= 0)
{
buffer = Math.Min(buffer, sum - coins[i]);
}
}
if (buffer == sum && sum == 0m)
return 0;
if(buffer == sum && sum != 0m)
{
return Int32.MinValue;
}
int result = 1 + MinNumberOfCoinsToSumRecursiveDecimalVersion(Math.Min(buffer, sum), coins);
return result;
}
However my real is question is how do I deal with an array size when I do not know the size beforehand. Thanks btw for the decimal note... that would have been embarrassing at an interview.
public int MinNumberForCoinSum(int sum, decimal [] coins) {
// I assume there is a custom Util class, but it would be checking null, empty, or any other business requirement
foreach(var verification in VerificationUtil.GetArrayVerifications()) {
verification.Verify(coins);
}
if(sum < 0 ) { Throw new InvalidArgumentException()); }
return MinNumberOfCoinsToSumRecursiveDecimalVersion(sum, coins);
}
The classic solution to deal with unknown array sizes is to use an initial capacity and then start resizing when it gets full. The growth factor is typically 2. This is what most of the growing data structures in the .NET framework do (list, stack, queue etc.)
Forgive if I sound obnoxious: you are way off. The question has nothing to do with resizing arrays. Here is a solution.
public static int numberOfCoins(double[] coins, double sum){
int total = 0;
Arrays.sort(coins);
int amount = (int)(sum*100);//convert to int for precision
for(int i=coins.length-1; i>=0 && amount > 0; i--){
int coin = (int)(100*coins[i]);//convert to int for precision
total+=amount/coin;
amount%=coin;
}
if(amount>0)
return -1;
return total;
}//numberOfCoins
Test the code with
public static void main(String... args){
double[] den = {0.01,.10,.05,.25};
System.out.println(numberOfCoins(den,1.65));
}
EDIT TO HANDLE INT CASE:
In that case I recommend overloading the function. by adding below as well
public static int numberOfCoins(int[] coins, int sum){
int total = 0;
Arrays.sort(coins);
int amount = sum;
for(int i=coins.length-1; i>=0 && amount > 0; i--){
total+=amount/coins[i];
amount%=coins[i];
}
if(amount>0)
return -1;
return total;
}//numberOfCoins

Any more efficient method of converting a string integer to int than convert.toint32

Is there a more efficient method of converting a string integer to int rather than using Convert.ToInt32() in c#?
I have a program which converts a lot of strings to integers. These values are read from a text file in string format.
No, probably not, at least not by far. I tried this quick and dirty benchmark:
private static int toint(string s) {
int res = 0;
foreach (var c in s) {
res = 10*res + (c - '0');
}
return res;
}
static void Main() {
var s = DateTime.Now;
for (int i = 0 ; i != 10000000 ; i++) {
if (Convert.ToInt32("112345678") == 0) break;
}
var m = DateTime.Now;
for (int i = 0; i != 10000000; i++) {
if (toint("112345678") == 0) break;
}
Console.WriteLine("{0} {1}", DateTime.Now-m, m-s);
}
My toint method skips all sorts of validations, and gets a result that is only a 40% improvement on Convert.ToInt32: 1.14 s vs. 1.86 s.
Adding just a basic validation to the dirty toint eliminates its advantage almost entirely: this method
private static int toint(string s) {
int res = 0;
foreach (var c in s) {
if (Char.IsDigit(c))
res = 10*res + (c - '0');
}
return res;
}
runs in 1.62 s, or a 13% improvement while staying fundamentally incorrect.
Using this method:
private static int Parse(string s)
{
int value = 0;
for (var i = 0; i < s.Length; i++)
{
value = value*10 + (s[i] - '0');
}
return value;
}
I get 750 ms instead of 18+ seconds with int.Parse for 100M conversions.
I won't recommend it unless this is your real bottleneck and you don't care about any form of validation.
If you’re reading your integers from a Stream, then you could optimize by avoiding the overhead of initializing a string.
For example, assuming that your numbers will always be non-negative and terminated by a , character, you could use:
int num = stream.ReadByte() - '0';
byte next = (byte)stream.ReadByte();
while (next != ',')
{
num = num * 10 + next - '0';
next = (byte)stream.ReadByte();
}
This page benchmarks 4 techniques. The fastest method was as Romain wrote about above:
y = 0;
for (int i = 0; i < s[x].Length; i++)
y = y * 10 + (s[x][i] - '0');
Here are some other methods that were tested that proved almost 10x slower (where "s" is the array of strings the author used for conversion) :
int.Parse(s[x]);
Int32.TryParse(s[x], out y);
Convert.ToInt32(s[x]);
Convert.ToInt32() uses Int32.Parse() (with a little validation thrown in). Int32.Parse() in turn uses Number.Parse().
The actual implementation is about as fast as you could get unless you had significant knowledge regarding the input value (e.g. your input is always a fixed number of digits, it is never hex, has a certain precision, it is always unsigned, etc.)
private unsafe static Boolean NumberToInt64(ref NumberBuffer number, ref Int64 value) {
Int32 i = number.scale;
if (i > Int64Precision || i < number.precision) {
return false;
}
char* p = number.digits;
BCLDebug.Assert(p != null, "");
Int64 n = 0;
while (--i >= 0) {
if ((UInt64)n > (0x7FFFFFFFFFFFFFFF / 10)) {
return false;
}
n *= 10;
if (*p != '\0') {
n += (Int32)(*p++ - '0');
}
}
if (number.sign) {
n = -n;
if (n > 0) {
return false;
}
}
else {
if (n < 0) {
return false;
}
}
value = n;
return true;
}
I use the Convert.ToXYZ() methods extensively in my own base framework and in profiler sessions they represent a trivial amount of overhead even when called hundreds of times in a single operation (such as deserializing a complex object tree).
I have encountered places where it is possible to improve upon the performance of the BCL with a specialized algorithm, but this probably isn't one of them.

Converting a boolean array into a hexadecimal number

Is there an easy way to convert an array of boolean values into 8-bit hexadecimal equivlents? For example, if I have
bool[] BoolArray = new bool[] { true,false,true,true,false,false,false,true };
If true values=1 and false values=0 then I'd like a method or function that would convert the above array to 0xB1 (10110001).
Does there exist such a function or method to do this? I am using C#, by the way.
Yes, you can use the BitArray class. Something like this should do it:
BitArray arr = new BitArray(BoolArray);
byte[] data = new byte[1];
arr.CopyTo(data, 0);
If by "8-bit hexadecimal" you mean the string representation, you can use the BitConverter class for that:
string hex = BitConverter.ToString(data);
How about
static int BoolArrayToInt(bool[] arr)
{
if (arr.Length > 31)
throw new ApplicationException("too many elements to be converted to a single int");
int val = 0;
for (int i = 0; i < arr.Length; ++i)
if (arr[i]) val |= 1 << i;
return val;
}
static string ToHexStr(int i) { return i.ToString("X8"); }
note: an editor remarked that arr[0] is the LSB but he expected MSB. This is an API consideration, if you prefer your LSB to be at arr[length-1] just reverse the array before passing to that function.
The Binary part can be achieved through this method:
bool[] boolArray = {true, false, true} will give 101:
int BoolArrayToInt(bool[] bArray)
{
char[] caseChar = new char[bArray.Length];
for(int i = 0; i < bArray.Length; i++)
{
if (bArray[i] == true)
{
caseChar[i] = '1';
}
else
{
caseChar[i] = '0';
}
}
string caseString = new string(caseChar);
int caseNum = System.Convert.ToInt32(caseString);
return caseNum;
}

Most efficient way to reverse the order of a BitArray?

I've been wondering what the most efficient way to reverse the order of a BitArray in C#. To be clear, I don't want to inverse the Bitarray by calling .Not(), I want to reverse the order of the bits in the array.
Cheers,
Chris
public void Reverse(BitArray array)
{
int length = array.Length;
int mid = (length / 2);
for (int i = 0; i < mid; i++)
{
bool bit = array[i];
array[i] = array[length - i - 1];
array[length - i - 1] = bit;
}
}
For a long array and relative few uses, just wrap it:
class BitArrayReverse
{
private BitArray _ba;
public BitArrayReverse(BitArray ba) { _ba = ba; }
public bool this[int index]
{
get { return _ba[_ba.Length - 1 - index]; }
set { _ba[_ba.Length - 1 - index] = value; }
}
}
This will be the best way
to reverse MSB <-> LSB of any length using XOR in the for loop
public static BitArray BitsReverse(BitArray bits)
{
int len = bits.Count;
BitArray a = new BitArray(bits);
BitArray b = new BitArray(bits);
for (int i = 0, j = len-1; i < len; ++i, --j)
{
a[i] = a[i] ^ b[j];
b[j] = a[i] ^ b[j];
a[i] = a[i] ^ b[j];
}
return a;
}
// in 010000011010000011100b
// out 001110000010110000010b
Dim myBA As New BitArray(4)
myBA(0) = True
myBA(1) = False
myBA(2) = True
myBA(3) = True
Dim myBoolArray1(3) As Boolean
myBA.CopyTo(myBoolArray1, 0)
Array.Reverse(myBoolArray1)
myBA = New BitArray(myBoolArray1)
For a short but inefficient answer:
using System.Linq;
var reversedBa = new BitArray(myBa.Cast<bool>().Reverse().ToArray())
Because the size if fixed at 8-bits just the "table" lookup from below is sufficient -- when dealing with a plain byte a look-up is likely the quickest way. The extra overhead of BitSet to get/set the data may, however, nullify the look-up benefit. Also the initial build cost and persistent overhead need to be considered (but the values could be coded into an array literal ... ick!)
On the other hand, if the data is only 8 bit (ever), and "performance is important", why use a BitArray at all? A BitArray could always be used for the nice features, such as "exploding" to an Enumerable while C# already has decent byte bit manipulation built-in.
Assuming a more general case that the data is 8-bit aligned... but of some undetermined length
Is this actually better (faster, more efficient, etc) than just doing it "per item" in the BitArray? I have no idea but suspect not. I would definitely start with the "simple" methods -- this is here as just a proof-of-concept and may (or may not be) interesting to compare in a benchmark. Anyway, write for clarity first ... and the below is not it! (There is at least one bug in it -- I blame the extra complexity ;-)
byte reverse (byte b) {
byte o = 0;
for (var i = 0; i < 8; i++) {
o <<= 1;
o |= (byte)(b & 1);
b >>= 1;
}
return o;
}
byte[] table;
BitArray reverse8 (BitArray ar) {
if (ar.Count % 8 != 0) {
throw new Exception("no!");
}
byte[] d = new byte[ar.Count / 8];
ar.CopyTo(d, 0);
// this only works if the bit array is
// a multiple of 8. we swap bytes and
// then reverse bits in each byte
int mid = d.Length / 2;
for (int i = 0, j = d.Length - 1; i < mid; i++, j--) {
byte t = d[i];
d[i] = table[d[j]];
d[j] = table[t];
}
return new BitArray(d);
}
string tostr (BitArray x) {
return string.Join("",
x.OfType<bool>().Select(i => i ? "1" : "0").ToArray());
}
void Main()
{
table = Enumerable.Range(0,256).Select(v => reverse((byte)v)).ToArray();
{
byte[] s = new byte[] { 1, 0xff };
BitArray ar = new BitArray(s);
// linqpad :)
tostr(ar).Dump();
tostr(reverse8(ar)).Dump();
}
"--".Dump();
{
byte[] s = new byte[] { 3, 42, 19 };
BitArray ar = new BitArray(s);
// linqpad :)
tostr(ar).Dump();
tostr(reverse8(ar)).Dump();
}
}
Output:
1000000011111111
1111111100000001
--
110000000101010011001000
000100110101010000000011
The expr.Dump() is a LINQPad feature.
Adapted the answer from #TimLoyd and turned it into an extension for easier use.
public static BitArray Reverse(this BitArray array)
{
int length = array.Length;
int mid = (length / 2);
for (int i = 0; i < mid; i++)
{
bool bit = array[i];
array[i] = array[length - i - 1];
array[length - i - 1] = bit;
}
return new BitArray(array);
}
Usage:
var bits = new BitArray(some_bytes).Reverse();

Categories

Resources