I'm trying to find an algorithm that will allow me to do the following:
Imagine I have 10 boolean variables, and I want to try every combination, since my goal is to find ANY combination which will give as a result to one of my methods true (This method has lots of restrictions, which is why I want to test every possible combinations, and if there are no combinations that will solve the problem, then I want to notify the user this).
I hope it is understandable!
Try this:
for (int i = 0; i < (1 << 10); i++)
{
bool b1 = (i & (1 << 0)) != 0;
bool b2 = (i & (1 << 1)) != 0;
bool b3 = (i & (1 << 2)) != 0;
bool b4 = (i & (1 << 3)) != 0;
...
if (MyMethod(b1, b2, b3, b4, ...))
{
// Found a combination for which MyMethod returns true
}
}
You can, of course, also use LINQ:
var result = from b1 in new[] { false, true }
from b2 in new[] { false, true }
from b3 in new[] { false, true }
from b4 in new[] { false, true }
...
where MyMethod(b1, b2, b3, b4, ...)
select new { b1, b2, b3, b4, ... };
I finally came up with a more efficient method: Using binary numbers:
Let's say I want to test all possible boolean combinations out of 8 variables:
If I pick do the following I'll get to test every combination:
public string CombinationFinder()
{
for (int i = 0; i < 2 ^ 8; i++)
{
String ans = Convert.ToInt32(i, 2).ToString();
if (myMethod(ans))
{
return ans;
}
}
return null;
}
This will go from 0 to 255, which in binary means going from 00000000 to 11111111
where each digit take the value 0 or 1, which can be represented as boolean. In this example if there's no combination found the method will return null.
I know this is an old question, but waclock's answer doesn't compile (there's no exponent operator in C#). dtb's answer gets 99% of the way there, but doesn't handle unknown number of booleans, which is what this answer provides:
var props = typeof(TypeWithBooleans).GetProperties().Where(prop => prop.PropertyType == typeof(bool)).ToArray();
for (var i = 0; i < (1 << props.Length); ++i)
{
var combination = Enumerable.Range(0, props.Length).Select(j => (i & (1 << j)) != 0).ToArray();
if (MyMethod(combination)) {
// handle match
};
}
This assumes that all the booleans you care about are confined to a single class/struct, and that MyMethod uses a params array.
define a class like this:
class Bint
{
int num;
public bool this[int num]
{
get {return num << n & 0x1 == 1;}
}
public int Num
{
get {return num;}
set {num = value;}
}
}
and iterate through the numbers:
Bint n = new Bint();
for (int i = 0; i < Math.pow(2,10); i++)
{
n.Num = i;
f(n[0],n[1]...);
}
Related
I don't know to search or google it so I ask it here.
I have an array of integers with fixed size and exactly with this logic.
sample [1,2,4,8,16,32]
Now I am given a number for example 26. And I shall find the numbers whose sum will make this number, in this case is [2,8,16]
for a number of 20 it will be [4,16]
for 40 it is [8,32]
and for 63 it is all of these numbers [1,2,4,8,16,32]
What is the proper algorithm for that?
I know strictly that there is always this continuation that the number is double of the previous value.
as well as only the numbers from the given array will sum up to the given number and each number will be used only for once or none
If it will be in C# method that takes array of ints and an int value and returns the array of ints that contains the ints that sum up this number from the given array will be preferred.
Thank you
As you can see, the number are base-2, which means you can easily use shift.
You could try this:
private IEnumerable<int> FindBits(int value)
{
// check for bits.
for (int i = 0; i < 32; i++)
{
// shift 1 by i
var bitVal = 1 << i; // you could use (int)Math.Pow(2, i); instead
// check if the value contains that bit.
if ((value & bitVal) == bitVal)
// yep, it did.
yield return bitVal;
}
}
This method will check what bits are set and return them as an ienumerable. (which can be converted to an array of list)
Usage:
// find the bits.
var res = FindBits(40).ToArray();
// format it using the string.join
var str = $"[{string.Join(",", res)}]";
// present the results
Console.WriteLine(str);
Results in [8,32]
Extra info:
counter
00000001 = 1 = 1 << 0
00000010 = 2 = 1 << 1
00000100 = 4 = 1 << 2
00001000 = 8 = 1 << 3
00010000 = 16 = 1 << 4
00100000 = 32 = 1 << 5
01000000 = 64 = 1 << 6
10000000 = 128 = 1 << 7
Instead of writing all combinations you make a for loop which does the counter.
Some extra non-sense:
If you like lambda's, you could replace the FindBits with this:
private Func<int, IEnumerable<int>> FindBits = (int value) => Enumerable
.Range(0, 31)
.Select(i => 2 << i).Where(i => (value & i) == i);
But it's better to keep it simpel/readable.
First you should notice that
( 1 2 4 8 16 ... ) = (2^0 2^1 2^2 2^3 2^4 ... )
And that this is the same as finding a binary encoding for a decimal number. What you are looking for is an algorithm to transform a decimal or base 10 number to a binary or base 2 number.
The algorithm is pretty simple:
public List<int> dec_to_bin(int num)
{
List<int> return_list = new List<int>();
int index = 0;
int remainder = num;
int bit = 0;
while (remainder > 0)
{
bit = remainder % 2;
if (bit == 1 )
{
return_list.Add((int)Math.Pow(2, index));
}
remainder = remainder / 2;
index = index + 1;
}
return return_list;
}
There is a better way however that just uses the underlying encoding of the number which is already binary.
public List<int> dec_to_bin(int num)
{
List<int> return_list = new List<int>();
int value = 1;
while( value < num )
{
if( (value & num) == value )
{
return_list.Add(value);
}
value = value * 2;
}
return return_list;
}
Another way to state your requirement is "What are the unique powers of 2 that sum to a given integer?" Since computers work with powers of 2 natively, there are built-in goodies in most languages to do this very succinctly.
As a bonus, you can use existing .Net types and methods to eliminate the need to write your own loops.
Here's one approach:
IEnumerable<int> GetCompositePowersOf2(int input) =>
//convert to enumerable of bools, one for each bit in the
//input value (true=1, false=0)
new BitArray(new[] { input }).Cast<bool>()
// get power of 2 corresponding to the position in the enumerable
// for each true value, gets 0 for false values.
.Select((isOne, pos) => isOne ? (1 << pos) : 0)
//filter out the 0 values
.Where(pow => pow > 0);
I don't quite get the " takes array of ints " part, since this creation of sums only works with numbers that are the power of 2.
private int[] count (int num)
{
int factor = 0;
List<int> facts = new List<int>();
while (num > 0)
{
int counter = 0;
int div = num;
int remainder = 0;
while (remainder == 0)
{
remainder = div % 2;
div = div / 2;
counter++;
}
factor = 1;
for (int i = 1; i < counter; i++)
factor *= 2;
num = num - factor;
facts.Add(factor);
}
return (facts.ToArray());
}
My assignment is to search through the binary representation of a number and replace a matched pattern of another binary representation of a number. If I get a match, I convert the matching bits from the first integer into zeroes and move on.
For example the number 469 would be 111010101 and I have to match it with 5 (101). Here's the program I've written so far. Doesn't work as expected.
using System;
namespace Conductors
{
class Program
{
static void Main(string[] args)
{
//this is the number I'm searching for a match in
int binaryTicket = 469;
//This is the pattern I'm trying to match (101)
int binaryPerforator = 5;
string binaryTicket01 = Convert.ToString(binaryTicket, 2);
bool match = true;
//in a 32 bit integer, position 29 is the last one I would
//search in, since I'm searching for the next 3
for (int pos = 0; pos < 29; pos++)
{
for (int j = 0; j <= 3; j++)
{
var posInBinaryTicket = pos + j;
var posInPerforator = j;
int bitInBinaryTicket = (binaryTicket & (1 << posInBinaryTicket)) >> posInBinaryTicket;
int bitInPerforator = (binaryPerforator & (1 << posInPerforator)) >> posInPerforator;
if (bitInBinaryTicket != bitInPerforator)
{
match = false;
break;
}
else
{
//what would be the proper bitwise operator here?
bitInBinaryTicket = 0;
}
}
Console.WriteLine(binaryTicket01);
}
}
}
}
Few things:
Use uint for this. Makes things a hell of a lot easier when dealing with binary numbers.
You aren't really setting anything - you're simply storing information, which is why you're printing out the same number so often.
You should loop the x times where x = length of the binary string (not just 29). There's no need for inner loops
static void Main(string[] args)
{
//this is the number I'm searching for a match in
uint binaryTicket = 469;
//This is the pattern I'm trying to match (101)
uint binaryPerforator = 5;
var numBinaryDigits = Math.Ceiling(Math.Log(binaryTicket, 2));
for (var i = 0; i < numBinaryDigits; i++)
{
var perforatorShifted = binaryPerforator << i;
//We need to mask off the result (otherwise we fail for checking 101 -> 111)
//The mask will put 1s in each place the perforator is checking.
var perforDigits = (int)Math.Ceiling(Math.Log(perforatorShifted, 2));
uint mask = (uint)Math.Pow(2, perforDigits) - 1;
Console.WriteLine("Ticket:\t" + GetBinary(binaryTicket));
Console.WriteLine("Perfor:\t" + GetBinary(perforatorShifted));
Console.WriteLine("Mask :\t" + GetBinary(mask));
if ((binaryTicket & mask) == perforatorShifted)
{
Console.WriteLine("Match.");
//Imagine we have the case:
//Ticket:
//111010101
//Perforator:
//000000101
//Is a match. What binary operation can we do to 0-out the final 101?
//We need to AND it with
//111111010
//To get that value, we need to invert the perforatorShifted
//000000101
//XOR
//111111111
//EQUALS
//111111010
//Which would yield:
//111010101
//AND
//111110000
//Equals
//111010000
var flipped = perforatorShifted ^ ((uint)0xFFFFFFFF);
binaryTicket = binaryTicket & flipped;
}
}
string binaryTicket01 = Convert.ToString(binaryTicket, 2);
Console.WriteLine(binaryTicket01);
}
static string GetBinary(uint v)
{
return Convert.ToString(v, 2).PadLeft(32, '0');
}
Please read over the above code - if there's anything you don't understand, leave me a comment and I can run through it with you.
Consider the following enumeration:
[Flags]
public enum EnumWithUniqueBitFlags
{
None = 0,
One = 1,
Two = 2,
Four = 4,
Eight = 8,
}
[Flags]
public enum EnumWithoutUniqueFlags
{
None = 0,
One = 1,
Two = 2,
Four = 4,
Five = 5,
}
The first one has values such that any combination will produce a unique bit combination while the second one will not. I need to programmatically determine this. So far I had only been checking if every value was a power of two but this since this code will be used to consume Enums developed by others, it is not practical.
var values = Enum.GetValues(typeof(TEnum)).OfType<TEnum>().ToList();
for (int i = 0; i < values.Count; i++)
{
if (((int) ((object) values [i])) != ((int) Math.Pow(2, i)))
{
throw (new Exception("Whatever."));
}
}
As opposed to the code above how could programatically determine that the following Enum meets the bit combination uniqueness objective (without assumptions such as values being powers of 2, etc.)?
[Flags]
public enum EnumWithoutUniqueFlags
{
Two = 2,
Four = 9,
Five = 64,
}
Please ignore which integral type the enum derives from as well as the fact that values could be negative.
You could compare the bitwise OR of enum values with the arithmetic sum of enum values:
var values = Enum.GetValues(typeof(EnumWithoutUniqueFlags))
.OfType<EnumWithoutUniqueFlags>().Select(val => (int)val).ToArray();
bool areBitsUnique = values.Aggregate(0, (acc, val) => acc | val) == values.Sum();
EDIT
As the #usr mentioned, the code above works for positive values only.
Despite the fact that the OP requested to ignore:
Please ignore which integral type the enum derives from as well as the fact that values could be negative.
I'm glad to introduce more optimal single loop approach:
private static bool AreEnumBitsUnique<T>()
{
int mask = 0;
foreach (int val in Enum.GetValues(typeof(T)))
{
if ((mask & val) != 0)
return false;
mask |= val;
}
return true;
}
To make it work for other underlying type (uint, long, ulong), just change the type of the mask and val variables.
EDIT2
Since the Enum.GetValues method returns values in the ascending order of their unsigned magnitude, if you need to check for duplicates of zero value, you could use the following approach:
private static bool AreEnumBitsUnique<T>()
{
int mask = 0;
int index = 0;
foreach (int val in Enum.GetValues(typeof(T)))
{
if ((mask & val) != 0) // If `val` and `mask` have common bit(s)
return false;
if (val == 0 && index != 0) // If more than one zero value in the enum
return false;
mask |= val;
index += 1;
}
return true;
}
To be unique, the enum must have no bits in common with other enum values. The bitwise AND operation can be used for this.
for (int i = 0; i < values.Count; ++i)
{
for (int j = 0; j < values.Count; ++j)
{
if (i != j && ((values[i] & values[j]) != 0))
throw new Exception(...);
}
}
I would cast the enums to uints, do a bitwise not of a 0x0, use an xor and if the next value is less than the previous one you have a collision
public static bool CheckEnumClashing<TEnum>()
{
uint prev = 0;
uint curr = 0;
prev = curr = ~curr;
foreach(var target in Enum.GetValues(typeof(TEnum)).Select(a=>(uint)a))
{
curr ^=target;
if( curr <= prev )
return false;
prev = curr;
}
return true;
}
[Flags]
public enum MyEnum
{
None = 0,
Setting1 = (1 << 1),
Setting2 = (1 << 2),
Setting3 = (1 << 3),
Setting4 = (1 << 4),
}
I need to be able to somehow loop over every posible setting and pass the settings combination to a function. Sadly I have been unable to figure out how to do this
Not tested, use at your own risk, but should solve the problem generically enough. System.Enum is not a valid restriction as technically C# only allow inheritance in/with class the backend bypasses this for Enum and ValueType. So sorry for the ugly casting. It is also not horribly efficient but unless you are running this against a dynamically generated type it should only ever have to be done once per execution (or once period if saved).
public static List<T> GetAllEnums<T>()
where T : struct
// With C# 7.3 where T : Enum works
{
// Unneeded if you add T : Enum
if (typeof(T).BaseType != typeof(Enum)) throw new ArgumentException("T must be an Enum type");
// The return type of Enum.GetValues is Array but it is effectively int[] per docs
// This bit converts to int[]
var values = Enum.GetValues(typeof(T)).Cast<int>().ToArray();
if (!typeof(T).GetCustomAttributes(typeof(FlagsAttribute), false).Any())
{
// We don't have flags so just return the result of GetValues
return values;
}
var valuesInverted = values.Select(v => ~v).ToArray();
int max = 0;
for (int i = 0; i < values.Length; i++)
{
max |= values[i];
}
var result = new List<T>();
for (int i = 0; i <= max; i++)
{
int unaccountedBits = i;
for (int j = 0; j < valuesInverted.Length; j++)
{
// This step removes each flag that is set in one of the Enums thus ensuring that an Enum with missing bits won't be passed an int that has those bits set
unaccountedBits &= valuesInverted[j];
if (unaccountedBits == 0)
{
result.Add((T)(object)i);
break;
}
}
}
//Check for zero
try
{
if (string.IsNullOrEmpty(Enum.GetName(typeof(T), (T)(object)0)))
{
result.Remove((T)(object)0);
}
}
catch
{
result.Remove((T)(object)0);
}
return result;
}
This works by getting all the values and ORing them together, rather than summing, in case there are composite numbers included. Then it takes every integer up to the maximum and masking them with the reverse of each Flag, this causes valid bits to become 0, allowing us to identify those bits that are impossible.
The check at the end is for missing zero from an Enum. You can remove it if you are fine with always including a zero enum in the results.
Gave the expected result of 15 when given an enum containing 2,4,6,32,34,16384.
Since it's a flagged enum, why not simply:
Get the highest vale of the enum.
Calculate the amound of combinations, i.e. the upper bound.
Iterate over every combination, i.e. loop from 0 to upper bound.
An example would look like this
var highestEnum = Enum.GetValues(typeof(MyEnum)).Cast<int>().Max();
var upperBound = highestEnum * 2;
for (int i = 0; i < upperBound; i++)
{
Console.WriteLine(((MyEnum)i).ToString());
}
Here is a solution particular to your code sample, using a simple for loop (don't use, see update below)
int max = (int)(MyEnum.Setting1 | MyEnum.Setting2 | MyEnum.Setting3 | MyEnum.Setting4);
for (int i = 0; i <= max; i++)
{
var value = (MyEnum)i;
SomeOtherFunction(value);
}
Update: Here is a generic method that will return all possible combinations. And thank #David Yaw for the idea to use a queue to build up every combination.
IEnumerable<T> AllCombinations<T>() where T : struct
{
// Constuct a function for OR-ing together two enums
Type type = typeof(T);
var param1 = Expression.Parameter(type);
var param2 = Expression.Parameter(type);
var orFunction = Expression.Lambda<Func<T, T, T>>(
Expression.Convert(
Expression.Or(
Expression.Convert(param1, type.GetEnumUnderlyingType()),
Expression.Convert(param2, type.GetEnumUnderlyingType())),
type), param1, param2).Compile();
var initalValues = (T[])Enum.GetValues(type);
var discoveredCombinations = new HashSet<T>(initalValues);
var queue = new Queue<T>(initalValues);
// Try OR-ing every inital value to each value in the queue
while (queue.Count > 0)
{
T a = queue.Dequeue();
foreach (T b in initalValues)
{
T combo = orFunction(a, b);
if (discoveredCombinations.Add(combo))
queue.Enqueue(combo);
}
}
return discoveredCombinations;
}
public IEnumerable<TEnum> AllCombinations<TEnum>() where TEnum : struct
{
Type enumType = typeof (TEnum);
if (!enumType.IsEnum)
throw new ArgumentException(string.Format("The type {0} does not represent an enumeration.", enumType), "TEnum");
if (enumType.GetCustomAttributes(typeof (FlagsAttribute), true).Length > 0) //Has Flags attribute
{
var allCombinations = new HashSet<TEnum>();
var underlyingType = Enum.GetUnderlyingType(enumType);
if (underlyingType == typeof (sbyte) || underlyingType == typeof (short) || underlyingType == typeof (int) || underlyingType == typeof (long))
{
long[] enumValues = Array.ConvertAll((TEnum[]) Enum.GetValues(enumType), value => Convert.ToInt64(value));
for (int i = 0; i < enumValues.Length; i++)
FillCombinationsRecursive(enumValues[i], i + 1, enumValues, allCombinations);
}
else if (underlyingType == typeof (byte) || underlyingType == typeof (ushort) || underlyingType == typeof (uint) || underlyingType == typeof (ulong))
{
ulong[] enumValues = Array.ConvertAll((TEnum[]) Enum.GetValues(enumType), value => Convert.ToUInt64(value));
for (int i = 0; i < enumValues.Length; i++)
FillCombinationsRecursive(enumValues[i], i + 1, enumValues, allCombinations);
}
return allCombinations;
}
//No Flags attribute
return (TEnum[]) Enum.GetValues(enumType);
}
private void FillCombinationsRecursive<TEnum>(long combination, int start, long[] initialValues, HashSet<TEnum> combinations) where TEnum : struct
{
combinations.Add((TEnum)Enum.ToObject(typeof(TEnum), combination));
if (combination == 0)
return;
for (int i = start; i < initialValues.Length; i++)
{
var nextCombination = combination | initialValues[i];
FillCombinationsRecursive(nextCombination, i + 1, initialValues, combinations);
}
}
private void FillCombinationsRecursive<TEnum>(ulong combination, int start, ulong[] initialValues, HashSet<TEnum> combinations) where TEnum : struct
{
combinations.Add((TEnum)Enum.ToObject(typeof(TEnum), combination));
if (combination == 0)
return;
for (int i = start; i < initialValues.Length; i++)
{
var nextCombination = combination | initialValues[i];
FillCombinationsRecursive(nextCombination, i + 1, initialValues, combinations);
}
}
First, grab a list of all the individual values. Since you've got 5 values, that's (1 << 5) = 32 combinations, so iterate from 1 to 31. (Don't start at zero, that would mean to include none of the enum values.) When iterating, examine the bits in the number, every one bit in the iteration variable means to include that enum value. Put the results into a HashSet, so that there aren't duplicates, since including the 'None' value doesn't change the resulting enum.
List<MyEnum> allValues = new List<MyEnum>(Enum.Getvalues(typeof(MyEnum)));
HashSet<MyEnum> allCombos = new Hashset<MyEnum>();
for(int i = 1; i < (1<<allValues.Count); i++)
{
MyEnum working = (MyEnum)0;
int index = 0;
int checker = i;
while(checker != 0)
{
if(checker & 0x01 == 0x01) working |= allValues[index];
checker = checker >> 1;
index++;
}
allCombos.Add(working);
}
I usually don't want to update each variable representing the max of an enumeration, when I add a new member to an enumeration.
For example I dislike the statement Greg proposed:
int max = (int)(MyEnum.Setting1 | MyEnum.Setting2 | ... | MyEnum.SettingN);
Consider when you have several of these variabeles scattered throughout your solution and you decide to modify your enumeration. That surely isn't a desirable scenario.
I will admit in advance that my code is slower, but it is automatically correct after an enumeration has been modified, and I strive to code in such a robust manner. I'm willing to pay some computational penalty for that, C# is all about that anywayz. I propose:
public static IEnumerable<T> GetAllValues<T>() where T : struct
{
if (!typeof(T).IsEnum) throw new ArgumentException("Generic argument is not an enumeration type");
int maxEnumValue = (1 << Enum.GetValues(typeof(T)).Length) - 1;
return Enumerable.Range(0, maxEnumValue).Cast<T>();
}
This assumes the enumeration contains members for all powers of 2 up to a certain power(including 0), exactly like a flag-enumeration is usually used.
I'm probably a little late to the party I would like to leave my solution which also includes the values plus the possible text of the combination in form of ("V1 | V2", "V1 | V2 | V3", etc).
I took some aspects of the solutions proposed above, so thanks to all that had posted the previous answers :D.
Note: only work with Enum set as base 2 combinations.
public static Dictionary<int,string> GetCombinations( this Enum enu)
{
var fields = enu.GetType()
.GetFields()
.Where(f => f.Name != "value__")
.DistinctBy(f=> Convert.ToInt32(f.GetRawConstantValue()));
var result = fields.ToDictionary(f=>Convert.ToInt32(f.GetRawConstantValue()), f => f.Name);
int max = Enum.GetValues(enu.GetType()).Cast<int>().Max();
int upperBound = max * 2;
for (int i = 0 ; i <= upperBound ; i += 2)
{
string s = Convert.ToString(i, 2).PadLeft(Math.Abs(i-max),'0');
Boolean[] bits = s.Select(chs => chs == '1' ? true : false)
.Reverse()
.ToArray();
if (!result.ContainsKey(i))
{
var newComb = string.Empty;
for (int j = 1; j < bits.Count(); j++)
{
var idx = 1 << j;
if (bits[j] && result.ContainsKey(idx))
{
newComb = newComb + result[idx] + " | ";
}
}
newComb = newComb.Trim(new char[] { ' ', '|' });
if (!result.ContainsValue(newComb) && !string.IsNullOrEmpty(newComb))
{
result.Add(i, newComb);
}
}
}
return result;
}
Concluded with this version:
Without checks:
public IEnumerable<T> AllCombinations<T>() where T : struct
{
var type = typeof(T);
for (var combination = 0; combination < Enum.GetValues(type).Cast<int>().Max()*2; combination++)
{
yield return (T)Enum.ToObject(type, combination);
}
}
With some checks:
public IEnumerable<T> AllCombinations<T>() where T : struct
{
var type = typeof(T);
if (!type.IsEnum)
{
throw new ArgumentException($"Type parameter '{nameof(T)}' must be an Enum type.");
}
for (var combination = 0; combination < Enum.GetValues(type).Cast<int>().Max()*2; combination++)
{
var result = (T)Enum.ToObject(type, combination);
// Optional check for legal combination.
// (and is not necessary if all flag a ascending exponent of 2 like 2, 4, 8...
if (result.ToString() == combination.ToString() && combination != 0)
{
continue;
}
yield return result;
}
}
In C#, is it possible to perform a sum of two 32-bit integers without using things like if..else, loops etc?
That is, can it be done using only the bitwise operations OR (|), AND (&), XOR (^), NOT (!), shift left (<<) and shift right (>>)?
Here is an example for your amusement
unsigned int myAdd(unsigned int a, unsigned int b)
{
unsigned int carry = a & b;
unsigned int result = a ^ b;
while(carry != 0)
{
unsigned int shiftedcarry = carry << 1;
carry = result & shiftedcarry;
result ^= shiftedcarry;
}
return result;
}
The loop could be unrolled. Number of times it executes, depends on the number of bits set in operands, but it's never greater than the width of unsigned int. Once carry becomes 0, next iterations don't change anything.
Try this:
private int add(int a, int b) {
if(b == 0)
return a;
return add( a ^ b, (a & b) << 1);
}
Edit:
Corrected if statement
Think about how addition happens bit by bit. Shift the values to get each bit of each operand in turn, then look at the four possible values for the two bits and work out what the result bit should be and whether there's a carry bit to worry about. Then see how the result and carry can be caculated using the bitwise ops.
static int binaryadd(int x, int y)
{
while (x != 0)
{
int c = y & x;
y = y ^ x;
x = c << 1;
}
return y;
}
public static int getSum(int p, int q)
{
int carry=0, result =0;
for(int i=0; i<32; i++)
{
int n1 = (p & (1<<(i)))>>(i); //find the nth bit of p
int n2 = (q & (1<<(i)))>>(i); //find the nth bit of q
int s = n1 ^ n2 ^ carry; //sum of bits
carry = (carry==0) ? (n1&n2): (n1 | n2); //calculate the carry for next step
result = result | (s<<(i)); //calculate resultant bit
}
return result;
}
Taking 32 bit as int takes 32 bit. Thanks!!!
int Add(int a, int b)
{
int result = 0,
// carry now contains common set bits of "a" and "b"
carry = a & b;
if (Convert.ToBoolean(carry))
{
// Sum of bits of "a" and "b" where at least one
// of the bits is not set
result = a ^ b;
// carry is shifted by one so that adding it
// to "a" gives the required sum
carry = carry << 1;
result = add(carry, result);
}
else
{
result = a ^ b;
}
return result;
}
Sum of two bits can be performed using the XOR ^ operator and carry bit can be obtained by using AND & operator.
Provided a and b don't have set bits at the same position, then using ^ operator gives the sum of a and b.
Comments from geeksforgeeks
public int getSum(int a, int b) {
while(b!=0){
int temp=a;
a=a^b;
b=(temp&b)<<1;
}
return a;
}
int b = 25;
for (int t = 128; t > 0; t = t / 2)
{
if ((b & t) != 0) Console.Write("1 ");
if ((b & t) == 0) Console.Write("0 ");
}
Console.WriteLine();
//b = (sbyte)~b;
int e = 22;
for (int t = 128; t > 0; t = t / 2)
{
if ((e & t) != 0) Console.Write("1 ");
if ((e & t) == 0) Console.Write("0 ");
}
Console.WriteLine();
int c = b | e;
for (int t = 128; t > 0; t = t / 2)
{
if ((c & t) != 0) Console.Write("1 ");
if ((c & t) == 0) Console.Write("0 ");
}