Bit reverse numbers by N bits - c#

I am trying to find a simple algorithm that reverses the bits of a number up to N number of bits. For example:
For N = 2:
01 -> 10
11 -> 11
For N = 3:
001 -> 100
011 -> 110
101 -> 101
The only things i keep finding is how to bit reverse a full byte but thats only going to work for N = 8 and thats not always what i need.
Does any one know an algorithm that can do this bitwise operation? I need to do many of them for an FFT so i'm looking for something that can be very optimised too.

It is the C# implementation of bitwise reverse operation:
public uint Reverse(uint a, int length)
{
uint b = 0b_0;
for (int i = 0; i < length; i++)
{
b = (b << 1) | (a & 0b_1);
a = a >> 1;
}
return b;
}
The code above first shifts the output value to the left and adds the bit in the smallest position of the input to the output and then shifts the input to right. and repeats it until all bits finished. Here are some samples:
uint a = 0b_1100;
uint b = Reverse(a, 4); //should be 0b_0011;
And
uint a = 0b_100;
uint b = Reverse(a, 3); //should be 0b_001;
This implementation's time complexity is O(N) which N is the length of the input.
Edit in Dotnet fiddle

Here's a small look-up table solution that's good for (2<=N<=32).
For N==8, I think everyone agrees that a 256 byte array lookup table is the way to go. Similarly, for N from 2 to 7, you could create 4, 8, ... 128 lookup byte arrays.
For N==16, you could flip each byte and then reorder the two bytes. Similarly, for N==24, you could flip each byte and then reorder things (which would leave the middle one flipped but in the same position). It should be obvious how N==32 would work.
For N==9, think of it as three 3-bit numbers (flip each of them, reorder them and then do some masking and shifting to get them in the right position). For N==10, it's two 5-bit numbers. For N==11, it's two 5-bit numbers on either side of a center bit that doesn't change. The same for N==13 (two 6-bit numbers around an unchanging center bit). For a prime like N==23, it would be a pair of 8- bit numbers around a center 7-bit number.
For the odd numbers between 24 and 32 it gets more complicated. You probably need to consider five separate numbers. Consider N==29, that could be four 7-bit numbers around an unchanging center bit. For N==31, it would be a center bit surround by a pair of 8-bit numbers and a pair of 7-bit numbers.
That said, that's a ton of complicated logic. It would be a bear to test. It might be faster than #MuhammadVakili's bit shifting solution (it certainly would be for N<=8), but it might not. I suggest you go with his solution.

Using string manipulation?
static void Main(string[] args)
{
uint number = 269;
int numBits = 4;
string strBinary = Convert.ToString(number, 2).PadLeft(32, '0');
Console.WriteLine($"{number}");
Console.WriteLine($"{strBinary}");
string strBitsReversed = new string(strBinary.Substring(strBinary.Length - numBits, numBits).ToCharArray().Reverse().ToArray());
string strBinaryModified = strBinary.Substring(0, strBinary.Length - numBits) + strBitsReversed;
uint numberModified = Convert.ToUInt32(strBinaryModified, 2);
Console.WriteLine($"{strBinaryModified}");
Console.WriteLine($"{numberModified}");
Console.Write("Press Enter to Quit.");
Console.ReadLine();
}
Output:
269
00000000000000000000000100001101
00000000000000000000000100001011
267
Press Enter to Quit.

Related

Any fast way to check if two doubles has the same sign?

Any fast way to check if two doubles have the same sign? Assume the two doubles cannot be 0.
Potential solutions:
a*b > 0: One floating-point multiply and one comparison.
(a>0) == (b>0): Three comparisons.
Math.Sign(a) == Math.Sign(b): Two function calls and one comparison.
Speed comparison:
It's about what you'd expect (see experimental setup at the bottom):
a*b > 0: 0.42 ± 0.02s
(a>0) == (b>0): 0.49 ± 0.01s
Math.Sign(a) == Math.Sign(b): 1.11 ± 0.9s
Important notes:
As noted by greybeard in the comments, method 1 is susceptible to problems if the values multiply to something smaller than Double.Epsilon. Unless you can guarantee that the multiple is always larger than this, you should probably go with method 2.
Experimental setup:
The following code was run 16 times on http://rextester.com/.
public static void Main(string[] args)
{
double a = 1e-273;
double b = a;
bool equiv = false;
for(int i=0; i<100000000; ++i) {
equiv = THE_COMPARISON;
b += a;
}
//Your code goes here
Console.WriteLine(equiv);
}
The simplest and fastest way for IEEE 754 I know of is just using XOR on the MSB bits of both numbers. Here is a small C# example (note the inlining to avoid the function overhead):
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe static bool fpu_cmpsign(double a, double b)
{
byte* aa;
byte* bb;
aa = (byte*)(&a); // points to the a as 8bit integral type
bb = (byte*)(&b); // points to the b as 8bit integral type
return ((aa[7] ^ bb[7]) & 128) != 128;
}
Here result of +/- numbers combinations:
a b result
- - 1
- + 0
+ - 0
+ + 1
The idea is simple. The sign is stored in the highest bit (MSB) and XOR returns 1 for non equal bits so XOR the MSB of booth numbers together and negate the output. the [7] is just accessing highest BYTE of the double as 8 bit integral type so I can use CPU ALU instead FPU. If your platform has reversed order of BYTES then use [0] instead (MSByte first vs. LSByte first).
So what you need is just 3x 8 bit XORs for comparison and negation and 1x 8bit AND for extracting sign bit result only.
You can use unions instead of pointers and also use native bit-width for your platform to get best performance.
You could use:
if (copysign(x, y) == x)

C# How to remove the n-th bit in integer?

I am trying to find a way to remove a bit from an integer. The solution must not use string operations.
For example, I have the number 27, which is 11011 in binary.
I want to remove the third bit so it leaves me with 1011.
Or we have 182 (10110110), remove the 6th bit so the result is 1110110 (which is 118). I am trying to think of the algorithm how to do that, but so far no luck, and I can't find useful information on the internet.
I know how to use bitwise operators and how to extract or manipulate bits in integers (change values, exchange values etc), but I don't know how to 'remove' a certain bit.
I am not looking for code, just the logic of the operation. If anyone could help me, that would be awesome!
Regards,
Toni
No problem, just decompose the number into the "upper part" and the "lower part", and put them together without the middle bit that now disappeared.
Not tested:
uint upper = x & 0xFFFFFFF0;
uint lower = x & 7;
return (upper >> 1) | lower;
More generally: (also not tested)
uint upper = x & (0xFFFFFFFE << n);
uint lower = x & ((1u << n) - 1);
return (upper >> 1) | lower;
In order to do this you need two bit masks and a shift.
The first bit mask gives you the portion of the number above bit n, exclusive of the n-th bit. The mask is constructed as follows:
var top = ~((1U<<(n+1))-1); // 1111 1111 1000 000, 0xFF80
The second bit mask gives you the portion of the number below bit n, exclusive of the n-th bit:
var bottom = (1U<<n)-1; // 0000 0000 0011 1111, 0x003F
Comments above show the values for your second example (i.e. n == 6)
With the two masks in hand, you can construct the result as follows:
var res = ((original & top)>>1) | (original & bottom);
Demo.
You could use the following approach:
int value = 27;
string binary = Convert.ToString(value, 2);
binary = binary.Remove(binary.Length-3-1,1); //Remove the exact bit, 3rd in this case
int newValue = Convert.ToInt32(binary, 2);
Console.WriteLine(newValue);
Hope it helps!
int Place = 7;
int TheInt = 182;
string binary = Convert.ToString(TheInt, 2);
MessageBox.Show(binary.Remove(binary.Length - Place, 1));
Here is a version that needs slightly fewer operations than the solution by harold:
x ^ (((x >> 1) ^ x) & (0xffffffff << n));
The idea is that below n, bits are xored with zero, leaving them unchanged, while from n and above the two x xored cancel each other out, leaving x >> 1.
int a = 27;//int= 4byte equal to 32 bit
string binary = "";
for (int i = 0; i < 32; i++)
{
if ((a&1)==0)//if a's least significant bit is 0 ,add 0 to str
{
binary = "0" + binary;
}
else//if a's least significant bit is 1 ,add 1 to str
{
binary = "1" + binary;
}
a = a >> 1;//shift the bits left to right and delete lsb
//we are doing it for 32 times because integer have 32 bit.
}
Console.WriteLine("Integer to Binary= "+binary);
//Now you can operate the string(binary) however you want.
binary = binary.Remove(binary.Length-4,1);//remove 4st bit from str

Defining a bit[] array in C#

currently im working on a solution for a prime-number calculator/checker. The algorythm is already working and verry efficient (0,359 seconds for the first 9012330 primes). Here is a part of the upper region where everything is declared:
const uint anz = 50000000;
uint a = 3, b = 4, c = 3, d = 13, e = 12, f = 13, g = 28, h = 32;
bool[,] prim = new bool[8, anz / 10];
uint max = 3 * (uint)(anz / (Math.Log(anz) - 1.08366));
uint[] p = new uint[max];
Now I wanted to go to the next level and use ulong's instead of uint's to cover a larger area (you can see that already), where i tapped into my problem: the bool-array.
Like everybody should know, bool's have the length of a byte what takes a lot of memory when creating the array... So I'm searching for a more resource-friendly way to do that.
My first idea was a bit-array -> not byte! <- to save the bool's, but haven't figured out how to do that by now. So if someone ever did something like this, I would appreciate any kind of tips and solutions. Thanks in advance :)
You can use BitArray collection:
http://msdn.microsoft.com/en-us/library/system.collections.bitarray(v=vs.110).aspx
MSDN Description:
Manages a compact array of bit values, which are represented as Booleans, where true indicates that the bit is on (1) and false indicates the bit is off (0).
You can (and should) use well tested and well known libraries.
But if you're looking to learn something (as it seems to be the case) you can do it yourself.
Another reason you may want to use a custom bit array is to use the hard drive to store the array, which comes in handy when calculating primes. To do this you'd need to further split addr, for example lowest 3 bits for the mask, next 28 bits for 256MB of in-memory storage, and from there on - a file name for a buffer file.
Yet another reason for custom bit array is to compress the memory use when specifically searching for primes. After all more than half of your bits will be 'false' because the numbers corresponding to them would be even, so in fact you can both speed up your calculation AND reduce memory requirements if you don't even store the even bits. You can do that by changing the way addr is interpreted. Further more you can also exclude numbers divisible by 3 (only 2 out of every 6 numbers has a chance of being prime) thus reducing memory requirements by 60% compared to plain bit array.
Notice the use of shift and logical operators to make the code a bit more efficient.
byte mask = (byte)(1 << (int)(addr & 7)); for example can be written as
byte mask = (byte)(1 << (int)(addr % 8));
and addr >> 3 can be written as addr / 8
Testing shift/logical operators vs division shows 2.6s vs 4.8s in favor of shift/logical for 200000000 operations.
Here's the code:
void Main()
{
var barr = new BitArray(10);
barr[4] = true;
Console.WriteLine("Is it "+barr[4]);
Console.WriteLine("Is it Not "+barr[5]);
}
public class BitArray{
private readonly byte[] _buffer;
public bool this[long addr]{
get{
byte mask = (byte)(1 << (int)(addr & 7));
byte val = _buffer[(int)(addr >> 3)];
bool bit = (val & mask) == mask;
return bit;
}
set{
byte mask = (byte) ((value ? 1:0) << (int)(addr & 7));
int offs = (int)addr >> 3;
_buffer[offs] = (byte)(_buffer[offs] | mask);
}
}
public BitArray(long size){
_buffer = new byte[size/8 + 1]; // define a byte buffer sized to hold 8 bools per byte. The spare +1 is to avoid dealing with rounding.
}
}

How to store integers efficiently in bytes ?

I'm looking for a good and efficient way to store integers in bytes.
The situation is the following:
I have two integers, Value 1 is "1857" (11bit) and Value 2 is "14" (4bit) and 2 bytes (16bit).
What I'm looking for, is to store the 2 integers in the 2 bytes. This mean cut the first integer, put 8 bits in the first byte and the rest plus the second integer in the second byte. Also I need to get them back together.
Is there a way or .net class to do that?
I've found the BitConverter class, but thats not what I'm looking for because this class only convert one integer to an full byte array.
You could use bit operators for that: bitwise and (&), or (|), and shift left (<<) and right (>>):
int value1 = 1857;
int value2 = 14;
int result = value1 | (value2 << 11);
To get the original values back you have to reverse that:
int result1 = result & 0x7ff; // 1857
int result2 = result >> 11; // 14

Fastest way to sum digits in a number

Given a large number, e.g. 9223372036854775807 (Int64.MaxValue), what is the quickest way to sum the digits?
Currently I am ToStringing and reparsing each char into an int:
num.ToString().Sum(c => int.Parse(new String(new char[] { c })));
Which is surely horrifically inefficent. Any suggestions?
And finally, how would you make this work with BigInteger?
Thanks
Well, another option is:
int sum = 0;
while (value != 0)
{
int remainder;
value = Math.DivRem(value, 10, out remainder);
sum += remainder;
}
BigInteger has a DivRem method as well, so you could use the same approach.
Note that I've seen DivRem not be as fast as doing the same arithmetic "manually", so if you're really interested in speed, you might want to consider that.
Also consider a lookup table with (say) 1000 elements precomputed with the sums:
int sum = 0;
while (value != 0)
{
int remainder;
value = Math.DivRem(value, 1000, out remainder);
sum += lookupTable[remainder];
}
That would mean fewer iterations, but each iteration has an added array access...
Nobody has discussed the BigInteger version. For that I'd look at 101, 102, 104, 108 and so on until you find the last 102n that is less than your value. Take your number div and mod 102n to come up with 2 smaller values. Wash, rinse, and repeat recursively. (You should keep your iterated squares of 10 in an array, and in the recursive part pass along the information about the next power to use.)
With a BigInteger with k digits, dividing by 10 is O(k). Therefore finding the sum of the digits with the naive algorithm is O(k2).
I don't know what C# uses internally, but the non-naive algorithms out there for multiplying or dividing a k-bit by a k-bit integer all work in time O(k1.6) or better (most are much, much better, but have an overhead that makes them worse for "small big integers"). In that case preparing your initial list of powers and splitting once takes times O(k1.6). This gives you 2 problems of size O((k/2)1.6) = 2-0.6O(k1.6). At the next level you have 4 problems of size O((k/4)1.6) for another 2-1.2O(k1.6) work. Add up all of the terms and the powers of 2 turn into a geometric series converging to a constant, so the total work is O(k1.6).
This is a definite win, and the win will be very, very evident if you're working with numbers in the many thousands of digits.
Yes, it's probably somewhat inefficient. I'd probably just repeatedly divide by 10, adding together the remainders each time.
The first rule of performance optimization: Don't divide when you can multiply instead. The following function will take four digit numbers 0-9999 and do what you ask. The intermediate calculations are larger than 16 bits. We multiple the number by 1/10000 and take the result as a Q16 fixed point number. Digits are then extracted by multiplication by 10 and taking the integer part.
#define TEN_OVER_10000 ((1<<25)/1000 +1) // .001 Q25
int sum_digits(unsigned int n)
{
int c;
int sum = 0;
n = (n * TEN_OVER_10000)>>9; // n*10/10000 Q16
for (c=0;c<4;c++)
{
printf("Digit: %d\n", n>>16);
sum += n>>16;
n = (n & 0xffff) * 10; // next digit
}
return sum;
}
This can be extended to larger sizes but its tricky. You need to ensure that the rounding in the fixed point calculation always works correctly. I also did 4 digit numbers so the intermediate result of the fixed point multiply would not overflow.
Int64 BigNumber = 9223372036854775807;
String BigNumberStr = BigNumber.ToString();
int Sum = 0;
foreach (Char c in BigNumberStr)
Sum += (byte)c;
// 48 is ascii value of zero
// remove in one step rather than in the loop
Sum -= 48 * BigNumberStr.Length;
Instead of int.parse, why not subtract '0' from each digit to get the actual value.
Remember, '9' - '0' = 9, so you should be able to do this in order k (length of the number). The subtraction is just one operation, so that should not slow things down.

Categories