I really do not understand what is happening here but:
when I do:
colorIndex += len - stopPos;
for(int m = 0; m < len - stopPos; m++)
{
colorUniPos++;
}
it does not give me the same result as doing:
colorIndex += len - stopPos;
colorUniPos += len - stopPos;
I think it becomes off by one or something. Shouldn't both of these obtain the same result?
Thanks
This won't produce the same result if len - stopPos < 0
This is correct if len - stopPos is a positive value or zero, but for negative values colorUniPos just keeps its value because the loop isn't executed.
Related
I have the following C++ code:
return lineNum >= startLineNum
&& lineNum <= startLineNum + lines.size() - 1;
Here, lineNum is an int, startLineNum is an int, lines is a std::vector<std::string>, and lines.size() is of type size_t.
When lineNum is 2, startLineNum is 0, and lines.size() is 0, the code returns true even though false was expected. These values were the values displayed in the debugger.
Even after adding parentheses where possible:
return ((lineNum >= startLineNum)
&& (lineNum <= (startLineNum + lines.size() - 1)));
the code still incorrectly returns true.
When I refactor the code into this form:
int start = startLineNum;
int end = startLineNum + lines.size() - 1;
return lineNum >= start && lineNum <= end;
it now returns false as expected.
What is going on here? I have never come across this kind of strangeness before.
lines.size() is more than likely an unsigned type. (If lines is a std::vector for example it's certainly unsigned.)
So due to the rules of argument promotion, and the fact that the terms in
startLineNum + lines.size() - 1;
are grouped from left to right, they are all converted to unsigned types.
This means that 0 + 0 - 1 is std::numeric_limits<decltype(lines.size())>::max() - a large number indeed, and lineNum is most likely less than it.
The rule of thumb: never use a negative when working with unsigned types, unless you really know what you're doing.
In your case, restate the problem to
lineNum < startLineNum + lines.size()
My guess would be that
lineNum <= startLineNum + lines.size() - 1;
is all unsigned types. linenum is 2, the other two are 0, and 0-1 in unsigned arithmetic is something VERY large (if 4 byte something above 4 billion).
Do instead
lineNum + 1 <= startLineNum + lines.size();
and all should be fine.
I'm trying to do some stencil computation using Halide. So assuming a basic 5 point 2D stencil, to evaluate some value at cell i,j I need the values of i-1,j i-2,j, i+1,j i+2,j. Now the way this works in C++ is that I have a for statement:
for(int i = 2; i < max_i - 2; i++)
for(int j = 2; j < max_j - 2; j++)
Calculate out = some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j))
Now I'm trying to do the same thing with Halide. so I have a Buffer called in which has the same value as my input array in the C++ code. And I have a Func called out:
out(i,j) = select(i >= 2 && j >= 2, some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j)) ,0.0f)
When I run this code I get the following error:
Error:
Input buffer b0 is accessed at -1, which is before the min (0) in dimension 0
Aborted (core dumped)
From my understanding, the reason for this error is that the select statement evaluates both statements so eventhough I don't want to calculate anything for i and j values less than two, the function is evaluated at i = 0 and j = 0 and thus the invalid address access.
So is there anyway to do this in Halide? Are there any other equivalents for if/else statements?
Using a boundary condition will do what you want:
Func unbounded;
unbounded(i, j,) = some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j));
out(i, j) = BoundaryConditions::constant_exterior(unbounded, 0.0f, 2, width - 4, 2, height - 4)(i, j);
I believe you can use "Expr()" instead of "width - 4" or "height - 4" if you want the maximum unbounded.
The use if BoundaryConditions functions allows hinting the compiler which direction of the if/else construct is more likely.
I have this very weird issue going on. The function you will see in a moment is supposed to ensure that all elements (chars) in a 2D array are at there utmost position, that is, there is no empty space above any of the characters. For instance a board could look like this:
1 X * * X ^
2 * X ^ *
3 o o * X ^
4 o ^ X X X
5 ^ * X * ^
1 2 3 4 5
And there is an issue at (2,1) because there is an empty space above a non empty space.
My function does the sorting correctly but it deletes any character in the bottom row that has an empty space above it. I cannot, for the life of me, figure out why. Here is my sort function.
int bb_float_one_step(BBoard board){
int i,j;
for (i = 0; i < board->rows; i++){
for (j = 0; j < board->cols; j++){
if (board->boardDim[i][j] == None && (board->boardDim[i + 1][j] != None && i + 1 <= board->rows)){
char tmp = board->boardDim[i + 1][j];
board->boardDim[i + 1][j] = board->boardDim[i][j];
board->boardDim[i][j] = tmp;
}
}
}
for (i = 0; i < board->rows; i++){
for (j = 0; j < board->cols; j++){
printf("%c",board->boardDim[i][j]);}printf("\n");}
}
Below Is a picture of the full sequence, The Program prints a board. The user is asked to select a region to 'pop.' A function then replaces all the characters that are connected with a blank space. Then in the last portion of the picture you can see how the characters are deleted. The board that doesn't have a border is there because I was using it to check if the characters actually were deleted or not.
Thank you in advanced for 1, reading this whole post, and 2, any help you can give.
Since you are comparing current row with next row you should use for(i = 0; i < board->rows-1; i++)
Then in your complex if statement, get rid of && i <= board->rows. That should have been a less-than anyway, not less-than-or-equals. You're going out of bounds and getting garbage in your array.
You are checking the row beyond the maximum number of rows.
(board->boardDim[i + 1][j] != None && i + 1 <= board->rows)
That memory is not guaranteed to be 0. If it is not 0, your function will swap it in. If it is not human readable, printf won't print anything for it thereby shifting the | to the left.
I am trying to make a simple Arduino code for when a photocell reading is less than 900, it will add 1 to the CurrentNumber and display it on a 4 digit 7 segment display. The problem is that it wont stop adding one even though it's reading more than 1000.
void loop() {
photocellReading = analogRead(photocellPin);
Serial.print("Analog reading = ");
Serial.println(photocellReading); // the raw analog reading
photocellReading = 1023 - photocellReading;
if(photocellReading << 10){
CurrentNumber = CurrentNumber + 1;
}
displayNumber(CurrentNumber);
}
Your problem is in your if condition:
if(photocellReading << 10){
CurrentNumber = CurrentNumber + 1;
}
What you're essentially doing he is: shifting the bits of photocellReading to the left by 10 (which is equivalent to multiplying by 2^10 aka 1024). Most likely this means the only time this is ever going to be false is if the value of photocellReading was 0 to start with. (I say most likely because it depends on if the bits loop back around or not, but this is not entirely relevant).
tl;dr your code is conceptually equivalent to:
if((photocellReading * 1024) != 0){
CurrentNumber = CurrentNumber + 1;
}
What I'm guessing you wanted to do (considering you subtracted 1023, which coincidentally is 1024 - 1) is:
if(photocellReading < 1024){ // again 1024 == 2^10
CurrentNumber = CurrentNumber + 1;
}
Ok, here's the function I'm a bit mystified by(Little rusty bitwise operators)
void two_one(unsigned char *in,int in_len,unsigned char *out)
{
unsigned char tmpc;
int i;
for(i=0;i<in_len;i+=2){
tmpc=in[i];
tmpc=toupper(tmpc);
if((tmpc<'0'||tmpc>'9') && (tmpc<'A'||tmpc>'F'))tmpc='F';
if(tmpc>'9')
tmpc=toupper(tmpc)-'A'+0x0A;
else
tmpc-='0';
tmpc<<=4; //Confused here
out[i/2]=tmpc;
tmpc=in[i+1];
tmpc=toupper(tmpc);
if((tmpc<'0'||tmpc>'9') && (tmpc<'A'||tmpc>'F'))tmpc='F';
if(tmpc>'9')
tmpc=toupper(tmpc)-'A'+0x0A;
else
tmpc-='0';
out[i/2]|=tmpc; //Confused Here
}
}
I marked the two places that I don't quite understand.
If anyone could help me convert those pieces to Vb.Net, or at least help me understand what's going on there, that'd be awesome.
Thanks.
Update
So this is what I came up with, but it's not quite giving me back the right data...Anything look wrong here?
Public Function TwoOne(ByVal inp As String) As String
Dim temp As New StringBuilder()
Dim tempc As Char
Dim tempi As Byte
Dim i As Integer
Dim len = inp.Length
inp = inp + Chr(0)
For i = 0 To len Step 2
If (i = len) Then Exit For
tempc = Char.ToUpper(inp(i))
If ((tempc < "0"c Or tempc > "9"c) AndAlso (tempc < "A"c Or tempc > "F"c)) Then
tempc = "F"c
End If
If (tempc > "9"c) Then
tempc = Char.ToUpper(tempc)
tempc = Chr(Asc(tempc) - Asc("A"c) + &HA)
Else
tempc = Chr(Asc(tempc) - Asc("0"c))
End If
tempc = Chr(CByte(Val(tempc)) << 4)
Dim tempcA = tempc
tempc = Char.ToUpper(inp(i + 1))
If ((tempc < "0"c Or tempc > "9"c) AndAlso (tempc < "A"c Or tempc > "F"c)) Then
tempc = "F"c
End If
If (tempc > "9"c) Then
tempc = Char.ToUpper(tempc)
tempc = Chr(Asc(tempc) - Asc("A"c) + &HA)
Else
tempc = Chr(Asc(tempc) - Asc("0"c))
End If
temp.Append(Chr(Asc(tempcA) Or Asc(tempc)))
Next
TwoOne = temp.ToString()
End Function
tmpc <<= 4 shifts the bits in tmpc 4 places to the left, then assigns the value back to tmpc. Hence if tmpc was 00001101, it becomes 11010000
out[i/2]|=tmpc bitwise-ors the array value with tmpc. Hence if out[i/2] is 01001001 and tmpc is 10011010, then out[i/2] becomes 11011011
EDIT (updated question):
The lines tmpc-='0'; in the original are not exactly the same as your new code tempc = "0"c. -= subtracts the value from the variable, and hence you need tempc = tempc - "0"c or similar
tmpc<<=4; (or tmpc = tmpc << 4;) shifts tmpc left by 4 bits.
out[i/2]|=tmpc; (or out[i/2] = out[i/2] | tmpc;) bitwise-ORs out[i/2] with tmpc.