My question is, is there a way in C# with a starting bit location to find the next binary digit within a byte that has a specified value of 0 or 1 without iteration (looking for the highest performance option).
As an example, if you had 10011 and started at the first bit (far right) and searched for the first 0, it would be the 3rd place going right to left. If you then started at the 3rd place and wanted to find the next 1, it would be at the 5th place (far left).
Thanks for any help and feel free to let me know if I need to provide anything further.
Edit: Here is my current code.
private int GetBinarySegment(uint uiValue, int iStart, int iMaxBits, byte bValue)
{
int r = 0; uiValue >>= iStart;
if (uiValue == 0) return iMaxBits - iStart;
while ((uiValue & 1) == bValue) { uiValue >>= 1; r++; }
return r;
}
There are ways, but they're ugly because there's no _BitScanForward or equivalent intrinsic. Still, you can actually compute this thing efficiently without needing a huge table.
First step: make a number that has a 1 at the position you're searching for and 0 everywhere else.
If searching for a 1, that means x & -x. If searching for a 0, use ~x & (x + 1).
Then, use one of the many ways to emulate either bitscan (there is only one set bit now, so it doesn't matter which side you search from). Some ways to do that are detailed here (not in C#, but you can convert them).
Use a lookup table. That is, precalculate a 2D array indexed by byte value and current position. You can do a separate table for zeros and ones, or you can combine it.
So for your example, you start at bit 0 of the number 19. That happens to be a 1. So if you lookup nextBit[19][0] it should return 1, and so on. Here's what a combined lookup table might look like. It shows the next bit for both 0s and 1s:
nextBit[19][0] = 1 // 1
nextBit[19][1] = 4 // 1
nextBit[19][2] = 3 // 0
nextBit[19][3] = 4 // 0
nextBit[19][4] = 0 // 1
nextBit[19][5] = 6 // 0
nextBit[19][6] = 7 // 0
Obviously there is no 'next' for bit 7, and if 'next' returns 0, there are no more of that particular bit.
I may have interpreted your question incorrectly, but this technique can be modified to suit your purposes. I initially thought you wanted to navigate through all 1-bits or 0-bits. If instead you want to skip over consecutive 1-bits, then you just arrange your table in that way. Or indeed, you can have a 'next' for both 0 and 1 at each position.
Related
I am trying to understand why the .. operator works the way it does, for example:
var data = new []{0,1,2,3,4,5,6,7,8,9,10};
var test = data[1..4]; // This returns array with 1,2,3
Logically, I would assume the result would be either 1,2,3,4 or 2,3 (if the last index isn't included then the first one shouldn't also)
or
var test = data[0..]; // This returns array with 0,1,2,3,4,5,6,7,8,9,10 (zero at index 0 is also included)
var test = data[^0..]; // This returns array with nothing, where i would expect 10, since 10 is at index zero if we traverse the array backwards
I know there must be a reason why it was designed to work like that, but I can't seem to figure it out, so what is the purpose of this behavior?
Thank you.
Why is the end index not included, but the start index is?
This is known as a half open range, and there are already questions asking about this in Python and C++. Essentially, the main advantage of this is that:
The length of the range is exactly (end - start).
You don't need to add/minus 1 as much in range-based algorithms
To slice something in half at an index, you can use the same index: x[..i] gives you the first half, and x[i..] gives you the second half. i.e. x[..i] concatenated with i[i..] is equal to x itself.
If a range's end is equal to another's start, the two ranges are immediately next to each other, and no overlapping.
Why is data[^0..] empty?
This is documented clearly. ^n means Length - n, so ^0 means data.Length - 0 here, which is just data.Length. data[data.Length..] is clearly empty.
It's simple enough. Consider the following:
var data = new []{0,1,2,3,4,5,6,7,8,9,10};
var test = data[0..10];
The 0 to 10, implies that it will select 11 items, if the last was inclusive. You have to start at 0, as C# indexes are zero based, and you'd need a -1 to include the first, if they were both exlusive.
As mentioned in the documentation:
A range specifies the start and end of a range. Ranges are exclusive, meaning the end isn't included in the range. The range [0..^0] represents the entire range, just as [0..sequence.Length] represents the entire range.
The data[^0..]; statements means, starting from the 0 position, bring whatever is below it. The ^ operator works inversly for the same reasons. (^0 is not inclusive of 0)
There have been many questions but i can't seem to find the why in the answers. It's usually: no, replace this with this or this should work.
My task is to create a program that asks the user to input a 3 digit positive integer (decimal) that converts it to octal.
For example, on paper: To convert the number 112 to octal. (8 is the base number for octal.)
These are the steps you would take:
112 / 8 = 14 remainder = 0
14 / 8 = 1 remainder = 6
1 / 8 = 0 remainder = 1
Remainder from bottom to up is the octal number that represents 112 in decimal.
So the octal number for 112 is 160.
I found the following program on the internet but i don't understand it fully.
The comments in the program are mine. Could anyone explain it to me please?
//declaration and initialization of variables but why is there an array?
int decimalNumber, quotient, i = 1, j;
int[] octalNumber = new int[100];
//input
Console.WriteLine("Enter a Decimal Number :");
decimalNumber = int.Parse(Console.ReadLine());
quotient = decimalNumber;
//as long as quotient is not equal to 0, statement will run
while (quotient != 0)
{
//this is how the remainder is calculated but it is then put in an array + 1, i don't understand this.
octalNumber[i++] = quotient % 8;
//divide the number given by the user with the octal base number
quotient = quotient / 8;
}
Console.Write("Equivalent Octal Number is ");
//i don't understand the code below here aswell.
for (j = i - 1; j > 0; j--)
Console.Write(octalNumber[j]);
Console.Read();
Any help is truly appreciated.
The first thing to understand is: this is a terrible way to solve this problem. The code is full of odd choices; it looks like someone took a bad C solution of this problem and translated it to C# without applying careful thought or using good practices. If you are trying to learn how to understand crappy code you find on the internet, this is a great example. If you are trying to learn how to design good code, this is a great example of what not to do.
//declaration and initialization of variables but why is there an array?
There's an array because we wish to store all the octal digits, and an array is a convenient mechanism for storing a number of data of the same type.
But we could ask some more pertinent questions here:
Why of size 100? It's not wrong, but that's enormously larger than necessary. What thought process led to 100 being chosen? Why wasn't that thought process documented anywhere?
Why an array of int? We're outputting text, which is a sequence of chars. It would seem more natural to have a bunch of chars.
Why an array? Since we are building a first-in-last-out data structure, a stack seems more appropriate. Or why not simply accumulate a string? That's inefficient if the string is large, but an octal string from a 32 bit integer is never large!
Why does the program produce output to the console? Surely a better factored program would have a method that takes an int and returns an octal string, which can then be printed.
Why do some of the variables have descriptive names and some have undescriptive names? Is the author of the code deliberately trying to confuse the reader? Or did they simply not think about it very carefully?
Why does i - apparently the current index into the array -- start at one?! This is simply bizarre. Arrays start at zero in C#.
What happens if you type in a negative number? Try it!
What happens if you type in zero?
We then go on to:
decimalNumber = int.Parse(Console.ReadLine());
This code presumes that the typed-in text is a legal integer, which is not guaranteed. So this program can crash. TryParse should be used, and the failure mode should be handled.
// this is how the remainder is calculated but it is
// then put in an array + 1, i don't understand this.
octalNumber[i++] = quotient % 8;
The author of the code thinks they are being clever. This is too much cleverness. Rewrite the code in your head to how it should have been implemented in the first place. First, rename i to currentIndex. Next, produce one side effect per statement, not two:
while (quotient != 0)
{
octalNumber[currentIndex] = quotient % 8;
currentIndex += 1;
quotient = quotient / 8;
}
Now it should be clear what is going on.
// I don't understand the code below here as well.
for (j = i - 1; j > 0; j--)
Console.Write(octalNumber[j]);
Do a little example. Suppose the number is 14, which is 16 in octal. First time through the loop we put 6 in slot 1. Next time through, we put 1 in slot 2. So the array is {0, 6, 1, 0, 0, 0, 0 ... } and i is 3. We wish to output 16. So we loop j from i-1 to 1, and print out 1 then 6.
So, exercise for you: write this program again, this time using the conventions of a well-designed C# program. Put your attempt on the code review site and people will be happy to give you tips on how to improve it.
This is already built into .NET, Convert.ToString already does this.
In your code, just after you have decimalNumber = int.Parse(...) you can do this:
Console.WriteLine(Convert.ToString(decimalNumber, 8));
Console.Read();
and then remove the rest of the code.
Now, if you're not asking how to do octal conversion in .NET but actually how that code works, here's how it works:
This loop does the heavy lifting:
1 while (quotient != 0)
{
//this is how the remainder is calculated but it is then put in an array + 1, i don't understand this.
2 octalNumber[i++] = quotient % 8;
//divide the number given by the user with the octal base number
3 quotient = quotient / 8;
}
I added some numbers to the lines to make it easier writing a description.
Basically, the loop does this (lines above correspond to points below).
As long as we have a number to convert (ie. we're still not done), loop.
Figure out the least significant digit, this is the remainder after dividing by 8, which is handled by the remainder operator, %, store this digit into the array in the next position.
Divide by 8 to get rid of that least significant digit and move all the other digits one up
Then loop back.
However, since we essentially found all the digits from the rightmost side towards the left, the loop at the end writes them back out in their opposite order.
As an exercise to the reader, try to figure out how the code in the question behaves if you:
Input a negative number
Input 0
(hint, it doesn't behave correctly but Convert.ToString does)
An array is used because they are calculating each digit every interation of the while loop. (e.g.) {0, 6, 1}
The last part of the program is printing each digit out, starting with the last item in the array and moving to the first. in this case it would print out:
160
My apologies if this has been asked/answered before but I'm honestly not even sure how to word this as a question properly. I have the following bit pattern:
0110110110110110110110110110110110110110110110110110110110110110
I'm trying to perform a shift that'll preserve my underlying pattern; my first instinct was to use right rotation ((x >> count) | (x << (-count & 63))) but the asymmetry in my bit pattern results in:
0011011011011011011011011011011011011011011011011011011011011011 <--- wrong
The problem is that the most significant (far left) bit ends up being 0 instead of the desired 1:
1011011011011011011011011011011011011011011011011011011011011011 <--- right
Is there a colloquial name for this function I'm looking for? If not, how could I go about implementing this idea?
Additional Information:
While the question is language agnostic I'm currently trying to solve this using C#.
The bit patterns I'm using are entirely predictable and always have the same structure; the pattern starts with a single zero followed by n - 1 ones (where n is an odd number) and then repeats infinitely.
I'd like to accomplish this without conditional operations since they'd defeat the purpose of using bitwise manipulation in the first place but maybe I have no choice...
You've got a number structured like this:
B16 B15 B14 B13 B12 B11 B10 B09 B08 B07 B06 B05 B04 B03 B02 B01 B00
? 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0
The ? needs to appear in the MSB (B15, or B63, or whatever) after the shift. Where does it come from? Well, the closest copy is found n places to the right:
B13 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0
^--------------/
If your word has width w, this is 1 << (w-n)
*
So you can do:
var selector = 1 << (w-n);
var rotated = (val >> 1) | ((val & selector) << (n-1));
But you may want a multiple shift. Then we need to build a wider mask:
? 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0
* * * * *
Here I've chosen to pretend n = 6, it just needs to be a multiple of the basic n, and larger than shift. Now:
var selector = ((1UL << shift) - 1) << (w - n);
var rotated = (val >> shift) | ((val & selector) << (n - shift));
Working demonstration using your pattern: http://rextester.com/UWYSW47054
It's easy to see that the output has period 3, as required:
1:B6DB6DB6DB6DB6DB
2:DB6DB6DB6DB6DB6D
3:6DB6DB6DB6DB6DB6
4:B6DB6DB6DB6DB6DB
5:DB6DB6DB6DB6DB6D
6:6DB6DB6DB6DB6DB6
7:B6DB6DB6DB6DB6DB
8:DB6DB6DB6DB6DB6D
9:6DB6DB6DB6DB6DB6
10:B6DB6DB6DB6DB6DB
11:DB6DB6DB6DB6DB6D
Instead of storing a lot of repetitions of a pattern, just store one recurrence and apply modulo operations on the indexes
byte[] pattern = new byte[] { 0, 1, 1 };
// Get a "bit" at index "i", shifted right by "shift"
byte bit = pattern[(i - shift + 1000000 * byte.Length) % byte.Length];
The + 1000000 * byte.Length must be greater than the greatest expected shift and ensures that we get a posistive sum.
This allows you to store patterns of virtually any length.
An optimization would be to store a mirrored version of the pattern. You could then shift left instead of right. This would simplify the index calculation
byte bit = pattern[(i + shift) % byte.Length];
Branchless Answer after a poke by #BenVoigt:
Get the last bit b by doing (n & 1);
Return n >> 1 | b << ((sizeof(n) - 1).
Original Answer:
Get the last bit b by doing (n & 1);
If b is 1, right shift the number by 1 bit and bitwise-OR it with 1 << (sizeof(n) - 1);
If b is 0, just right shift the number by 1 bit.
The problem was changed a bit through the comments.
For all reasonable n, the following problem can be solved efficiently after minimal pre-computation:
Given an offset k, get 64 bits starting at that position in the stream of bits that follows the pattern of (zero, n-1 ones) repeating.
Clearly the pattern repeats with a period of n, so only n different ulongs have to be produced for every given value of n. That could either be done explicitly, constructing all of them in pre-processing (they could be constructed in any obvious way, it doesn't really matter since that only happens once), or left more implicitly by storing only two ulongs per value for n (this works under the assumption that n < 64, see below) and then extracting a range from them with some shifting/ORing. Either way, use offset % n to compute which pattern to retrieve (since the offset is increasing in a predictable manner, no actual modulo operation is required[1]).
Even with the first method, memory consumption will be reasonable since this optimization is only an optimization for low n: in particular for n > 64 there will be fewer than 1 zero per word on average, so the "old fashioned way" of visiting every multiple of n and resetting that bit starts to skip work while the above trick would still visit every word and would not be able anymore to reset multiple bits at once.
[1]: if there are multiple n's in play at the same time, a possible strategy is keeping an array offsets where offsets[n] = offset % n, which could be updated according to: (not tested)
int next = offsets[n] + _64modn[n]; // 64 % n precomputed
offsets[n] = next - (((n - next - 1) >> 31) & n);
The idea being that n is subtracted whenever next >= n. Only one subtraction is needed since the offset and thing added to the offset are already reduced modulo n.
This offset-increment can be done with System.Numerics.Vectors, which is very feature-poor compared to actual hardware but is just about able to do this. It can't do the shift (yes, it's weird) but it can implement a comparison in a branchless way.
Doing one pass per value of n is easier, but touches lots of memory in a cache unfriendly manner. Doing lots of different n at the same time may not be great either. I guess you'd just have to bechmark that..
Also you could consider hard-coding it for some low numbers, something like offset % 3 is fairly efficient (unlike offset % variable). This does take manual loop-unrolling which is a bit annoying, but it's actually simpler, just big in terms of lines of code.
I was trying to recreate my C++ factor program from a few years ago in my new language C#. All I could remember is that it possibly involved a modulo, and possibly didn't. I knew that it involved at least one for and if statement. However, when I started trying to recreate it I kept getting nothing near what should be. I thought it had something to do with me not understanding loops, but it turns out I understand loops just fine. What I don't understand is how to use the modulo when performing math operations.
for instance what am I doing when I say something like:
(ignore that it might not actually work, it's just an example)
if(12 % 2 == 0)
{
Console.WriteLine("I don't understand.");
}
This kind of thing I don't quite have a grasp of yet. I realize that it is taking the remainder, and that's all I can grasp, not how it's actually used in real programming. I managed to get my factor program to work in C# after a bit of thinking and tinkering, it again doesn't mean I understand this operator or its uses. I no longer have access to the old C++ file.
The % (modulo) operator yields the remainder from the division. In your example the remainder is equal to 0 and the if evaluates to true (0 == 0). A classic example is when it's used to see if a number is even or not.
if (number % 2 == 0) {
// even
} else {
// odd
}
Think of modulo like a circle with a pointer (spinner), easiest example is a clock.
Notice how at the top it is zero.
The modulo function maps any value to one of those values on the spinner, think of the value to the left of the % as the number of steps around the spinner, and the second value as the number of total steps in the spinner, so we have the following.
0 % 12 = 0
1 % 12 = 1
12 % 12 = 0
13 % 12 = 1
We always start at 0.
So if we go 0 steps around a 12 step spinner we are still at 0, if we go 1 step from zero we are on 1, if we go 12 steps we are back at 0. If we go 13 we go all the way around and end at 1 again.
I hope this helps you visualize it.
It helps when you are using structures like an array, and you want to cycle through them. Imagine you have an array of the days of the week, 7 elements (mon-sunday). You want to always display the day 3 days from the current day. well Today is tuesday, so the array element is days[1], if we want to get the day 3 days from now we do days[1+3]; now this is alright, but what if we are at saturday (days[5]) and want to get 3 days from there? well we have days[5+3] which is an index out of bounds error as our array has only 7 elements (max index of 6) and we tried to access the 8th element.
However, knowing what you know about modulos and spinners now you can do the following:
string threeDaysFromNow = days[(currentDay + 3)%7]; When it goes over the bounds of the array, it wraps around and starts at the beginning again. There are many applications for this. Just remember the visualization of spinners, that is when it clicked in my head.
The modulo operator % returns the remainder of a division operation. For example, where 13 / 5 = 2, 13 % 5 = 3 (using integer math).
It's a common tactic to check a value against % 2 to see if it is even. If it is even, the remainder will be 0, otherwise it will be 1.
As for your specific use of it, you are doing 12 % 2 which is not only 0, but will always be 0. That will always make the if condition 12 % 2 == 0 true, which makes the if rather redundant.
as mentioned, it's commonly used for checking even/odd but also can use it to iterate loops at intervals, or split files into mod chunks. i personally use mod for clock face type problems as my data often navigates a circle.
the register is in mod for example an 8 bit register rolls over at 2^8 so so can force compliance into a register size var = mod(var, 256)
and the last thing i know about mod is that it is used in checksum and random number generation, but i haven't gone into the why for those. at all
An example where you could use this is in indexing arrays in certain for loops. For example, take the simple equation that defines the new pixel value of a resampled image using bicubic interpolation:
where
Don't worry what bicubic interpolation exactly is for the moment, we're just concerned about executing what seems to be two simple for loops: one for index i and one for index j. Note that the vector 'a' is 16 numbers long.
A simple for loop someone would try could be:
int n= 0;
for(int i = 0; i < 4; ++i)
{
for(int j = 0; i < 4; ++j)
{
pxy += a[n] * pow(x,i) * pow(y,j); // p(x,y)
n++; // n = 15 when finished
}
}
Or you could do it in one for loop:
for(int i = 0; i < 16; ++i)
{
int i_new = floor(i / 4.0); // i_new provides indices 0-3 incrementing every 4 iterations of loop
int j_new = i % 4; // j_new is reset to 0 when i is a multiple of 4
pxy += a[i] * pow(x,i_new) * pow(y,j_new); // p(x,y)
}
Printing i_new and j_new in the loop:
i_new j_new
0 0
0 1
0 2
0 3
1 0
1 1
1 2
1 3
2 0
2 1
2 2
2 3
3 0
3 1
3 2
3 3
As you can see, % can be very useful.
So I have the following RotateLeft algorithm in C#:
public static ushort RotateLeft(ushort value, int count)
{
int left = value << count;
int right = value >> (16 - count);
return (ushort)(left | right);
}
Does this algorithm differ if the numbering scheme is different?
By numbering scheme I mean if it's MSB-0 or LSB-0
MSB-0
0 7
1 0 0 1 0 1 1 0
LSB-0
7 0
1 0 0 1 0 1 1 0
Say I wanted to shift left by 1, does having a different numbering scheme affect the algorithm?
It looks like that algorithm is agnostic of the underlying system's little- or big- endianness. That is to say, it will work the same regardless of the numbering scheme, since the OR operation adds the shifted bits back in on the other side before returning. Assuming you're using it for bit-level operations and flag checks, this might be all you need.
Without knowing how it fits into the rest of your program it's hard to say whether it will work the way you expect across different platforms using opposite bit numbering schemes. For example, if you run this on a device using MSB-0 and write some shifted data to a binary file, then read that binary data back in on a device using LSB-0, it probably won't be what you're expecting.
If your goal is to have your software work the same across differently-endian systems, take a look at the .NET BitConverter Class. If you're using this for efficient mathematical operations, the static BitConverter.IsLittleEndian field will let you check the underlying architecture so that you can shift the other way or reverse binary data accordingly.