for(int y = 0; y < 5; y++)
{
char cst1[2] = {info[x+2], info[x+3]};
char cst2[2] = {info[x+5], info[x+6]};
sales[count][atoi(&info[x]) - 1] = atoi(cst1) + atoi(cst2);
x += 8;
}
Every time i do the following code the atoi(cst1) value is multiplied by two then added and atoi(cst2) is multiplied by 100 then added cant figure out why
cst1 and cst2 don't appear to be NUL-terminated.
char cst1[] = {info[x+2], info[x+3], '\0'};
char cst2[] = {info[x+5], info[x+6], '\0'};
Related
i'm trying to turn a 1d array of strings into a 2d array of chars using:
'''''''''''''''
variables
'''''''''''''''
const int width = 20;
const int height = 20;
char arena[width][height];
string arenaline[height];
'''''''''''''''
setup
'''''''''''''''
arenaline[1] = "####################";
arenaline[2] = "#..................#";
arenaline[3] = "#..................#";
arenaline[4] = "###...###..###...###";
arenaline[5] = "#.......#..#.......#";
arenaline[6] = "###...###..###...###";
arenaline[7] = "#..................#";
arenaline[8] = "###...###..###...###";
arenaline[9] = "#.......#..#.......#";
arenaline[10] = "#########..#########";
arenaline[11] = "###..............###";
arenaline[12] = "###.#####..#####.###";
arenaline[13] = "###.####....####.###";
arenaline[14] = "###.####....####.###";
arenaline[15] = "#.....###..###.....#";
arenaline[16] = "#.....###..###.....#";
arenaline[17] = "#..#..###..###..#..#";
arenaline[18] = "#.....###..###.....#";
arenaline[19] = "#.....###..###.....#";
arenaline[20] = "####################";
'''''''''''''''
conversion
'''''''''''''''
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
arena[j][i] = arenaline[i].substr(j,1);
}
}
I want it to convert from the substring to a char so I can use it in an array.
I can't use a string instead of chars because it breaks the function where the array is output to the console.
substr returns a string. string is not implicitly converted to char for "single character" strings.
The correct way to adress single characters of strings is string::operator[] or string::at().
Well, here is my code and I am having a problem because my n is not increasing:
#define N 100
#define N_EQUATIONS 18 + 2
//initial values
int v = 1;
int cai = 2;
int caSR = 3;
int nai = 4;
int ki = 5;
int dvdt = 18;
double V_init = -87.5;
double Cai_init=1.0e-4;
double cansr=1.2;
double cajsr=cansr;
double CaSR_init = cansr + cajsr;
double Nai_init = 7;
double Ki_init = 145;
double u[N + 1][N_EQUATIONS + 1];
double Im[N + 1];
int main () {
int n = 0;
for ( n = 0; n <= N; n++) {
printf("n=%.18f\n", n);
u[n][v] = V_init;
//printf("t=%.18f\n", u[n][v]);
u[n][cai] = Cai_init;
//printf("cai=%.18f\n", u[n][cai]);
u[n][caSR] = CaSR_init;
u[n][nai] = Nai_init;
u[n][ki] = Ki_init;
u[n][dvdt] = 0.0;//check it
tapend[n] = 0.0;
tapstart[n] = 0.0;
}
}
Sorry if it is a stupid question and the answer is staring me at the eyes..
P.S. see the new revised code
You are probably just confused because your printf is incorrect:
printf("n=%.18f\n", n);
should be, e.g.
printf("n=%18d\n", n);
Currently you just print garbage in your loop (0 in your case, it seems, but it could be anything), so this may give the incorrect impression that n is not incrementing correctly.
Note that if you enable compiler warnings (and compiler warnings should always be enabled), then the compiler would have pointed out this mistake to you. Always enable compiler warnings and always take notice of any warnings, understand them, and fix them.
I have a 20 x 20 array and need to iterate over it by reading a 4 x 4 array. I thought I could do this with pointed assignment, but it does not do much except force close
const char SOURCE[20][20];
const char **pointer;
for(int x = 0; x < 20; x+=4)
{
for(int y = 0; y < 20; y+=4)
{
pointer = (const char **)&SOURCE[x][y];
printGrid(pointer);
}
}
void printGrid(const char **grid)
{
// do something usefull
}
Just casting a pointer to a different type doesn't change the
type of what it points to (and will usually lead to undefined
behavior, unless you really know what you're doing). If you
cannot change printGrid, you'll have to create an array of
pointers on the fly:
for ( int x = 0; x < 20; x += 4 ) {
for ( int y = 0; y < 20; y += 4 ) {
char const* p4[4] =
{
source[x] + y,
source[x + 1] + y,
source[x + 2] + y,
source[x + 3] + y
};
printGrid( p4 );
}
}
A pointer to a pointer is not the same as an array of arrays.
You can however use a pointer to an array instead:
const char (*pointer)[20];
You of course need to update the printGrid function to match the type.
As for the reason why a pointer-to-pointer and an array-of-array (also often called a matrix) see e.g. this old answer of mine that shows the memory layout of the two.
Your 2D-array is of type char:
const char SOURCE[20][20];
When you are iterating through it, you can either look at the char or reference the address with a char*:
for(int x = 0; x < 20; x+=4)
{
for(int y = 0; y < 20; y+=4)
{
printGrid(SOURCE[x][y]); // do this unless you need to do something with pointer
}
}
Then you can make printGrid with either of the following signatures:
void printGrid(const char& grid)
{
// do something usefull
}
or
void printGrid(const char* grid)
{
// do something usefull
}
Extending James's Answer, you may change your code as below as it sees that the it passes pointer to an array of 4 char rather than just array of char.
for(int x = 0; x < 20; x+=4)
{
for(int y = 0; y < 20; y+=4)
{
char const (*p4[4])[4] =
{
(const char(*)[4])(SOURCE[x] + y),
(const char(*)[4])(SOURCE[x + 1] + y),
(const char(*)[4])(SOURCE[x + 2] + y),
(const char(*)[4])(SOURCE[x + 3] + y)
};
}
}
Anyway have any idea how to do this?
Let's say i have
char x[] = "ABCD";
and i want to put it into an int, so i'll have
int y = 'ABCD';
I can only put individual chars, such as int y = x[0]; The purpose is to find the decimal representation, but i want the decimal representation of "ABCD" not just "A".
Finally i would use sprintf(dest, "%.2u", value); to get the decimal representation of the char.
EDIT:
I dont understand why, but for "ABCD" this code works
//unrolled bit ops
const char* x = "ABCD";
uint32_t y = 0;
y |= (uint32_t(x[0]) << 24); //MSB
y |= (uint32_t(x[1]) << 16);
y |= (uint32_t(x[2]) << 8);
y |= (uint32_t(x[3]) /*<< 0*/);
however, per instance if i use "(¸þ¶" i dont get the same result.
EDIT2 **:
I've tried your last edit Sam, but it still doesnt work. The value i'm getting is "4294967294" as opposed to "683212470" the correct value.
I also did this
int h1 = '(';
int h2 = '¸';
int h3 = 'þ';
int h4 = '¶';
Output:
40
-72
-2
-74
I googled for the complete ascii table, and i found out that for "þ" the value is "254". I suppose it has something to do with this... i also tried with usigned but no good results.
edit3: If i replace const char *x = "(¸þ¶" with int x[] = {40, 184, 254, 182}; (decimal representation of each character, it works. I can understand where things go wrong, but i have no idea how to fix it.
You need to assure int alignment for that char array for a proper cast or do a memcpy into that int.
Also take care of the integer's endianness! Furthermore, usage of C99 integer types such as uint32_t, will also help to make your code portable.
See this question for how to convert the bits:
strict aliasing and alignment
EDIT:
What R. Martinho Fernandes means, might be this (not tested):
//unrolled bit ops
const char* x = "ABCD";
uint32_t y = 0;
y |= (uint32_t(uint8_t(x[0])) << 24); //MSB
y |= (uint32_t(uint8_t(x[1])) << 16);
y |= (uint32_t(uint8_t(x[2])) << 8);
y |= (uint32_t(uint8_t(x[3])) /*<< 0*/);
Above example avoids specific code for any endianness
EDIT 2:
For dynamic char arrays (assuming leading zero chars if less than 4 have to be converted):
const char* x = "ABC";
size_t nChars = 3;
assert(0 < nChars && nChars <= sizeof(uint32_t));
uint32_t y = 0;
int shift = (nChars*8)-8;
for(size_t i = 0;i < nChars;++i)
{
y |= (uint32_t(uint8_t(x[i])) << shift);
shift -= 8;
}
I have created a sample program if this is what you want.
Include the needed headers (stdio.h, stdlib.h, math.h, string.h)
unsigned long convertToInt(char *x);
void main() {
char x[] = "ABCD";
unsigned long y = 0;
y = convertToInt(x);
printf("Numeric value = %lu\n", y);
}
unsigned long convertToInt(char *x) {
unsigned long num = 0, i, n;`
char hex_c;
for(i = 0; i< strlen(x); i++) {
hex_c = x[i];
if (hex_c >= '0' && hex_c <= '9') {
n = hex_c - '0';
} else if (hex_c >= 'A' && hex_c <= 'F') {
n = 10 + hex_c - 'A';
} else if (hex_c >= 'a' && hex_c <= 'f') {
n = 10 + hex_c - 'a';
} else {
printf("Wrong input");
return 0;
}
num += n * (pow(16, (strlen(x) - i - 1)));
}
return num;
}
I am trying to write an android app which needs to calculate gaussian and laplacian pyramids for multiple full resolution images, i wrote this it on C++ with NDK, the most critical part of the code is applying gaussian filter to images abd i am applying this filter with horizontally and vertically.
The filter is (0.0625, 0.25, 0.375, 0.25, 0.0625)
Since i am working on integers i am calculating (1, 4, 6, 4, 1)/16
dst[index] = ( src[index-2] + src[index-1]*4 + src[index]*6+src[index+1]*4+src[index+2])/16;
I have made a few simple optimization however it still is working slow than expected and i was wondering if there are any other optimization options that i am missing.
PS: I should mention that i have tried to write this filter part with inline arm assembly however it give 2x slower results.
//horizontal filter
for(unsigned y = 0; y < height; y++) {
for(unsigned x = 2; x < width-2; x++) {
int index = y*width+x;
dst[index].r = (src[index-2].r+ src[index+2].r + (src[index-1].r + src[index+1].r)*4 + src[index].r*6)>>4;
dst[index].g = (src[index-2].g+ src[index+2].g + (src[index-1].g + src[index+1].g)*4 + src[index].g*6)>>4;
dst[index].b = (src[index-2].b+ src[index+2].b + (src[index-1].b + src[index+1].b)*4 + src[index].b*6)>>4;
}
}
//vertical filter
for(unsigned y = 2; y < height-2; y++) {
for(unsigned x = 0; x < width; x++) {
int index = y*width+x;
dst[index].r = (src[index-2*width].r + src[index+2*width].r + (src[index-width].r + src[index+width].r)*4 + src[index].r*6)>>4;
dst[index].g = (src[index-2*width].g + src[index+2*width].g + (src[index-width].g + src[index+width].g)*4 + src[index].g*6)>>4;
dst[index].b = (src[index-2*width].b + src[index+2*width].b + (src[index-width].b + src[index+width].b)*4 + src[index].b*6)>>4;
}
}
The index multiplication can be factored out of the inner loop since the mulitplicatation only occurs when y is changed:
for (unsigned y ...
{
int index = y * width;
for (unsigned int x...
You may gain some speed by loading variables before you use them. This would make the processor load them in the cache:
for (unsigned x = ...
{
register YOUR_DATA_TYPE a, b, c, d, e;
a = src[index - 2].r;
b = src[index - 1].r;
c = src[index + 0].r; // The " + 0" is to show a pattern.
d = src[index + 1].r;
e = src[index + 2].r;
dest[index].r = (a + e + (b + d) * 4 + c * 6) >> 4;
// ...
Another trick would be to "cache" the values of the src so that only a new one is added each time because the value in src[index+2] may be used up to 5 times.
So here is a example of the concepts:
//horizontal filter
for(unsigned y = 0; y < height; y++)
{
int index = y*width + 2;
register YOUR_DATA_TYPE a, b, c, d, e;
a = src[index - 2].r;
b = src[index - 1].r;
c = src[index + 0].r; // The " + 0" is to show a pattern.
d = src[index + 1].r;
e = src[index + 2].r;
for(unsigned x = 2; x < width-2; x++)
{
dest[index - 2 + x].r = (a + e + (b + d) * 4 + c * 6) >> 4;
a = b;
b = c;
c = d;
d = e;
e = src[index + x].r;
I'm not sure how your compiler would optimize all this, but I tend to work in pointers. Assuming your struct is 3 bytes... You can start with pointers in the right places (the edge of the filter for source, and the destination for target), and just move them through using constant array offsets. I've also put in an optional OpenMP directive on the outer loop, as this can also improve things.
#pragma omp parallel for
for(unsigned y = 0; y < height; y++) {
const int rowindex = y * width;
char * dpos = (char*)&dest[rowindex+2];
char * spos = (char*)&src[rowindex];
const char *end = (char*)&src[rowindex+width-2];
for( ; spos != end; spos++, dpos++) {
*dpos = (spos[0] + spos[4] + ((spos[1] + src[3])<<2) + spos[2]*6) >> 4;
}
}
Similarly for the vertical loop.
const int scanwidth = width * 3;
const int row1 = scanwidth;
const int row2 = row1+scanwidth;
const int row3 = row2+scanwidth;
const int row4 = row3+scanwidth;
#pragma omp parallel for
for(unsigned y = 2; y < height-2; y++) {
const int rowindex = y * width;
char * dpos = (char*)&dest[rowindex];
char * spos = (char*)&src[rowindex-row2];
const char *end = spos + scanwidth;
for( ; spos != end; spos++, dpos++) {
*dpos = (spos[0] + spos[row4] + ((spos[row1] + src[row3])<<2) + spos[row2]*6) >> 4;
}
}
This is how I do convolutions, anyway. It sacrifices readability a little, and I've never tried measuring the difference. I just tend to write them that way from the outset. See if that gives you a speed-up. The OpenMP definitely will if you have a multicore machine, and the pointer stuff might.
I like the comment about using SSE for these operations.
Some of the more obvious optimizations are exploiting the symmetry of the kernel:
a=*src++; b=*src++; c=*src++; d=*src++; e=*src++; // init
LOOP (n/5) times:
z=(a+e)+(b+d)<<2+c*6; *dst++=z>>4; // then reuse the local variables
a=*src++;
z=(b+a)+(c+e)<<2+d*6; *dst++=z>>4; // registers have been read only once...
b=*src++;
z=(c+b)+(d+a)<<2+e*6; *dst++=z>>4;
e=*src++;
The second thing is that one can perform multiple additions using a single integer. When the values to be filtered are unsigned, one can fit two channels in a single 32-bit integer (or 4 channels in a 64-bit integer); it's the poor mans SIMD.
a= 0x[0011][0034] <-- split to two
b= 0x[0031][008a]
----------------------
sum 0042 00b0
>>4 0004 200b0 <-- mask off
mask 00ff 00ff
-------------------
0004 000b <-- result
(The Simulated SIMD shows one addition followed by a shift by 4)
Here's a kernel that calculates 3 rgb operations in parallel (easy to modify for 6 rgb operations in 64-bit architectures...)
#define MASK (255+(255<<10)+(255<<20))
#define KERNEL(a,b,c,d,e) { \
a=((a+e+(c<<1))>>2) & MASK; a=(a+b+c+d)>>2 & MASK; *DATA++ = a; a=DATA[4]; }
void calc_5_rgbs(unsigned int *DATA)
{
register unsigned int a = DATA[0], b=DATA[1], c=DATA[2], d=DATA[3], e=DATA[4];
KERNEL(a,b,c,d,e);
KERNEL(b,c,d,e,a);
KERNEL(c,d,e,a,b);
KERNEL(d,e,a,b,c);
KERNEL(e,a,b,c,d);
}
Works best on ARM and on 64-bit IA with 16 registers... Needs heavy assembler optimizations to overcome register shortage in 32-bit IA (e.g. use ebp as GPR). And just because of that it's an inplace algorithm...
There are just 2 guardian bits between every 8 bits of data, which is just enough to get exactly the same result as in integer calculation.
And BTW: it's faster to just run through the array byte per byte than by r,g,b elements
unsigned char *s=(unsigned char *) source_array;
unsigned char *d=(unsigned char *) dest_array;
for (j=0;j<3*N;j++) d[j]=(s[j]+s[j+16]+s[j+8]*6+s[j+4]*4+s[j+12]*4)>>4;