Victor Morales Dionisio Victor Morales Dionisio - 7 days ago 5
C Question

error: invalid operands to binary ^ (have ‘double’ and ‘double’) - I'm not trying to use ^ as a power operator

I've been looking for an answer for this but could not find it. I'm not trying to use ^ as a power operator.

Here's my problem.
I'm trying to reproduce an interleaver from a digital TV standard (physical layer protocol). It is a project for school.
Here's the code I have so far in C:

#include <sys/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <stdbool.h>
#include <string.h>
#include <complex.h>
#include <math.h>

int main()
{
int Mmax = 32768;
int Nr = log10(Mmax)/log10(2);
printf("Nr = %i \n",Nr);

int Lfm = 42;

int i,j,k,l;

// Create array R'i
unsigned char Rli[Mmax][Nr];
for (i = 0; i < Mmax; i++)
memset(Rli[i], 0, sizeof(unsigned char)*(Nr));

for (i = 0; i < Mmax; i++)
{
for(j = 1; j < Nr; j++)
{
if(i == 0 || i == 1)
{
Rli[i][j] = 0;
}

else if(i == 2)
{
Rli[i][j] = 0;
if(j == Nr - 2)
Rli[i][j] = 1;
}

else
{
Rli[i][j+1] = Rli[i-1][j];
}
}

if(i > 2)
{
Rli[i][1] = (((Rli[i-1][14] ^ Rli[i-1][13] ) ^ Rli[i-1][12] ) ^ Rli[i-1][2]);
}
Rli[i][0] = 0;
}

// wire permutation for array R'i - creates array Ri

unsigned char Ri[Mmax][Nr];
for (i = 0; i < Mmax; i++)
memset(Ri[i], 0, sizeof(unsigned char)*(Nr));

for (i = 0; i < Mmax; i++)
{
Ri[i][1] = Rli[i][8]; //Rli[i][7];
Ri[i][2] = Rli[i][9]; //Rli[i][8];
Ri[i][3] = Rli[i][14]; //Rli[i][13];
Ri[i][4] = Rli[i][4]; //Rli[i][3];
Ri[i][5] = Rli[i][6]; //Rli[i][5];
Ri[i][6] = Rli[i][13]; //Rli[i][12];
Ri[i][7] = Rli[i][3]; //Rli[i][2];
Ri[i][8] = Rli[i][2]; //Rli[i][1];
Ri[i][9] = Rli[i][12]; //Rli[i][11];
Ri[i][10] = Rli[i][5]; //Rli[i][4];
Ri[i][11] = Rli[i][10]; //Rli[i][9];
Ri[i][12] = Rli[i][11]; //Rli[i][10];
Ri[i][13] = Rli[i][1]; //Rli[i][0];
Ri[i][14] = Rli[i][7]; //Rli[i][6];
}

// Offset generator Gk

int Gmax = floor(Lfm/2);
unsigned char Gk[Gmax][Nr];
for (i = 0; i < Gmax; i++)
memset(Gk[i], 0, sizeof(unsigned char)*Nr-1);

for (k = 0; k < Gmax; k++)
{
for(j = 0; j < Nr; j++)
{
if(k == 0)
{
Gk[k][j] = 1;
}

else
{
Gk[k][j+1] = Gk[k-1][j];
}
}

if(k > 0)
{
Gk[k][0] = ( Gk[k-1][14] ^ Gk[k-1][13] );
}

}

// interleaving sequence

int Ndata = 26303; // numero de data
unsigned char Hl[Ndata];
double H1[Ndata], H2[Ndata];
memset(Hl, 0, sizeof(unsigned char)*Ndata);
memset(H1, 0, sizeof(double)*Ndata);
memset(H2, 0, sizeof(double)*Ndata);

int p,indice;

// loop from page 107 of the physical layer protocol.
for (i = 0; i < Lfm; i++)
{
for (k = 0; k < Mmax; k++)
{
p = 0;
for (j = 0; j < Nr; j++) // sum
{
if(j >= 0 && j <= Nr - 2)
H1[p] += Ri[k][j]*pow(2,j);
else if(j >= 0 && j <= Nr - 1)
{
indice = floor(i/2);
H2[p] += Gk[indice][j]*pow(2,j);
}
}
/*****/ Hl[p] = ((i % 2)*pow(2,Nr-1) + H1[p] ) ^ H2[p]; /*****/
if (Hl[p] < Ndata)
p += 1;
}
}


the line between the /*****/ in the end generates an error when I try to compile.

freqint.c:146:43: error: invalid operands to binary ^ (have ‘double’ and ‘double’)

Hl[p] = ((i % 2)*pow(2,Nr-1) + H1[p] ) ^ H2[p];


I want to do the XOR operation there, but I can't get it right.

I'm taking this from:
http://atsc.org/wp-content/uploads/2016/10/A322-2016-Physical-Layer-Protocol.pdf

the interleaving sequence is on the bottom of page 107

How do I write my code to avoid that error message and still do an XOR?

Answer

As was stated in the comments, the ^ operator can't be used on a double, however you don't need to use double.

You're using two functions which return a double, namely pow and floor.

Each time you call pow, you pass 2 for the base. Raising 2 to a power can be done much more efficiently by left shifting the value 1 by the exponent.

Similarly, each time you call floor you're dividing an integer value by 2. Since integer division automatically drops the remainder of division (assuming you're working only with positive values), the call to floor doesn't buy you anything.

So change all instances of pow(2,x) to (1 << x), and change all instances of floor(x/2) to (x/2). Then you can declare H1 and H2 as arrays of unsigned int and you will be able to use the XOR operator ^.