I created a header file called ofdm.h which includes all the function prototypes. Then I created a source file called ofdm.c, which includes the source code of all the functions declared in ofdm.h . After that I started coding in main.c, but when I run it I get the error: undefined reference to '(function name)'. I get this error for all my functions.
Below you can find the source code of all my three files.
ofdm.h
#ifndef OFDM_H_INCLUDED
#define OFDM_H_INCLUDED
typedef struct {
double real, img;
} Complex;
char** split(char *s, const char *delim);
void parseComplex(Complex *c, char *line);
void rbits(short* buf, int nbits);
void printbinary(short* buf, int len);
void printcomplex(Complex* buf, int len);
long bin2dec(short *bin, int len);
void dec2bin(long dec, short *bin, int len);
void binaryadd(short *bin1, short *bin2, short *erg, int len);
void leftshift(short *bin,short *erg,int shifts, int len);
void binarymult(short *bin1, short *bin2, short *erg, int len);
void binarypower(short *bin,short *erg,int power, int len);
void scrambler(short *seed, short *input, short *output, int len, int seedlen);
void encoder(short *input, short *output, int inputlen);
void interleaver(short *input, short *output, int N_CBPS,int N_BPSC);
void deinterleaver(short *input, short *output, int N_CBPS,int N_BPSC);
void fixed_point(short* input, int nbits);
void fixed_point_complex(Complex* input, int nbits);
void defixed_point(short* input, int nbits);
void BPSKmapping(short* input, short* output, int nbits);
void BPSKdemapping(short* input, short* output, int nbits);
void QPSKmapping(short* input, Complex* output, int nbits);
void QPSKdemapping(Complex* input, short* output, int nbits);
void IFFT_BPSK(short* input, Complex* output, Complex* twidder);
void IFFT_QPSK(Complex* input, Complex* output, Complex* twidder);
double uniform(double a, double b);
double gauss(double mean, int SNRdb);
void ChannelModel(Complex R[], Complex S[], int SNRdb);
#endif
ofdm.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "ofdm.h"
char** split(char* string, const char* delim)
{
char* p;
int i = 0;
char** array = malloc(strlen(string) * sizeof(char*));
p = strtok(string, delim);
while(p != NULL)
{
array[i] = malloc(sizeof(char));
array[i++] = p;
p = strtok(NULL, delim);
}
return array;
}
void parseComplex(Complex *cmplx, char *number)
{
char *copy = number;
if(strchr(copy, ' ') != NULL)
{
char **result = split(copy, " ");
cmplx->real = atof(*result++);
char *sign = *result++;
cmplx->img = atof(*result++);
if(sign[0] == '-')
cmplx->img = -(cmplx->img);
}
else if(strchr(copy, 'j') != NULL)
{
cmplx->real = 0;
cmplx->img = atof(copy);
}
else
{
cmplx->real = atof(copy);
cmplx->img = 0;
}
}
void rbits(short* buf, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
buf[i] = (rand() % 2);
}
void printbinary(short* buf, int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("%d\t", buf[i]);
}
printf("\n\n\n");
}
void printcomplex(Complex* buf, int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("%.0lf %.0lf\t", buf[i].real, buf[i].img);
}
printf("\n\n");
}
long bin2dec(short *bin, int len)
{
long dec = 0;
int i;
for(i = 0;i < len;i++)
{
dec += bin[i]*pow(2.0,(double) (len - i -1));
}
return dec;
}
void dec2bin(long dec, short *bin, int len)
{
long temp = dec;
int i;
for(i = 0;i<len;i++)
{
bin[len - 1 - i] = temp % 2;
temp = temp/2;
}
}
void binaryadd(short *bin1, short *bin2, short *erg, int len)
{
int i;
short carry = 0;
short oldcarry = 0;
for(i = len - 1; i >= 0; i--)
{
if((bin1[i] + bin2[i] + oldcarry) > 1)
{
carry = 1;
}
else
{
carry = 0;
}
erg[i] = (bin1[i] + bin2[i] + oldcarry) % 2;
oldcarry = carry;
}
}
void leftshift(short *bin,short *erg,int shifts, int len)
{
int i;
for(i = 0;i < len - shifts;i++)
{
erg[i] = bin[i + shifts];
}
for(i = len - shifts;i < len;i++)
{
erg[i] = 0;
}
}
void binarymult(short *bin1, short *bin2, short *erg, int len)
{
int i;
short temp[len - 1];
for(i = 0;i < len;i++)
{
erg[i] = 0;
}
for(i = 0;i < len;i++)
{
if(bin2[i] == 1)
{
leftshift(bin1,temp,len - 1 - i,len);
binaryadd(temp,erg,erg,len);
}
}
}
void binarypower(short *bin,short *erg,int power, int len)
{
int i;
short temp[len - 1];
for(i = 0;i < len;i++)
{
temp[i] = 0;
}
temp[len - 1] = 1;
if(power > 1)
binarypower(bin,temp,power - 1,len);
binarymult(temp,bin,erg,len);
}
void scrambler(short *seed, short *input, short *output, int len, int seedlen)
{
int i;
short carry;
short sequence[len - 1];
for(i = 0; i < len; i++)
{
sequence[i] = (seed[0] + seed[3]) % 2;
carry = (seed[0] + seed[3]) % 2;
leftshift(seed,seed,1,seedlen);
seed[seedlen - 1] = carry;
output[i] = (sequence[i] + input[i]) % 2;
}
}
void encoder(short *input, short *output, int inputlen)
{
int i;
short SR[7] = {0,0,0,0,0,0,0};
short A;
short B;
for(i = 0; i < inputlen;i++)
{
leftshift(SR,SR,1,7);
SR[6] = input[i];
A = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) % 2;
B = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) % 2;
output[2*i] = A;
output[2*i + 1] = B;
}
}
/*
void decoder(short *input, short *output, int inputlen)
{
int i;
short SR[7] = {0}
short A;
short B;
short C1;
short C2;
for(i = 0; i < intputlen; i++)
{
leftshift(SR, SR, 1, 7)
SR[6] = input[i];
C1 = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) / 2;
C2 = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) / 2;
A = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) - (2 * C1);
B = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) - (2 * C2);
output[2*i] = A; // output[i/2] = A;
output[2*i + 1] = B; // output[i/2 + 1] = B;
}
}
*/
void interleaver(short *input, short *output, int N_CBPS,int N_BPSC)
{
int i;
int t;
int k;
int s;
short first_permutuation[N_CBPS - 1];
for (k = 0; k < N_CBPS; k++)
{
i = (N_CBPS/16)*(k % 16) + (k/16);
first_permutuation[i] = input[k];
}
s = fmax(N_BPSC/2,1);
for(i = 0; i < N_CBPS;i++)
{
t = s*(i/s) + (i + N_CBPS - ((16*i)/N_CBPS)) % s;
output[t] = first_permutuation[i];
}
}
void fixed_point(short* input, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] < 0)
input[i] *= 32768;
else input[i] *= 32767;
}
}
void fixed_point_complex(Complex* input, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i].real == -1 || input[i].img == -1)
input[i] *= 32768;
else input[i] *= 32767;
}
}
void defixed_point(short* input, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] < 0)
input[i] /= 32768;
else input[i] /= 32767;
}
}
void IFFT_BPSK(short* input, Complex* output, Complex* twidder)
{
int i, k;
for(i = 0; i < 64; i++)
{
for(k = 0; k < 64; k++)
{
output[i].real += (twidder[i][k].real * input[i]) / 64;
output[i].img += (twidder[i][k].img * input[i]) / 64;
}
}
}
void IFFT_QPSK(Complex* input, Complex* output, Complex* twidder)
{
int i, k;
for(i = 0; i < 64; i++)
{
for(k = 0; k < 64; k++)
{
output[i].real += (twidder[i][k].real * input[i].real) / 64;
output[i].img += (twidder[i][k].img * input[i].img) / 64;
}
}
}
void IFFT_QPSK2(Complex* input, Complex* output, Complex* twidder, int nbits)
{
int a, b, c, d, e, f, g, h, blocks;
int count1 = 7, count2 = 20, count3 = 28, count4 = 41;
int next = 0;
Complex ifft_qpsk_output[64];
blocks = nbits / 48;
for(a = 1; a <= blocks; a++)
{
// pilots
output[7].real = 32767;
output[21].real = 32767;
output[42].real = 32767;
output[56].real = -32768;
// some data
output[40].real = input[26 + (next * 48)].real;
output[40].img = input[26 + (next * 48)].img;
output[41].real = input[27 + (next * 48)].real;
output[41].img = input[27 + (next * 48)].img;
// zeroes
for(b = 28; b <= 39; b++)
output[b].real = 0;
// other data
for(c = 0; c <= 6; c++)
{
output[c].real = input[c + (next * 48)].real;
output[c].img = input[c + (next * 48)].img;
}
for(d = 8; d <= 20; d++)
{
output[d].real = input[count1++ + (next * 48)].real;
output[d].img = input[count1++ + (next * 48)].img;
}
for(e = 22; e <= 27; e++)
{
output[e].real = input[count2++ + (next * 48)].real;
output[e].img = input[count2++ + (next * 48)].img;
}
for(f = 43; f <= 55; f++)
{
output[f].real = input[count3++ + (next * 48)].real;
output[f].img = input[count3++ + (next * 48)].img;
}
for(h = 57; h <= 63; h++)
{
output[h].real = input[count4++ + (next * 48)].real;
output[h].img = input[count4++ + (next * 48)].img;
}
// IFFT function goes here
IFFT_QPSK(output, ifft_qpsk_output, twidder);
printcomplex(ifft_qpsk_output, 64);
next++;
}
}
void IFFT_BPSK2(short* input, short* output, Complex* twidder, int nbits)
{
int a, b, c, d, e, f, g, h, blocks;
int count1 = 7, count2 = 20, count3 = 28, count4 = 41;
int next = 0;
Complex ifft_bpsk_output[64];
blocks = nbits / 48;
for(a = 1; a <= blocks; a++)
{
// pilots
output[7] = 32767;
output[21] = 32767;
output[42] = 32767;
output[56] = -32768;
// some data
output[40] = input[26 + (next * 48)];
output[41] = input[27 + (next * 48)];
// zeroes
for(b = 28; b <= 39; b++)
output[b] = 0;
// other data
for(c = 0; c <= 6; c++)
output[c] = input[c + (next * 48)];
for(d = 8; d <= 20; d++)
output[d] = input[count1++ + (next * 48)];
for(e = 22; e <= 27; e++)
output[e] = input[count2++ + (next * 48)];
for(f = 43; f <= 55; f++)
output[f] = input[count3++ + (next * 48)];
for(h = 57; h <= 63; h++)
output[h] = input[count4++ + (next * 48)];
// IFFT function goes here
IFFT_BPSK(output, ifft_bpsk_output, twidder);
printcomplex(ifft_bpsk_output, 64);
next++;
}
}
void BPSKmapping(short* input, short* output, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] == 0)
output[i] = -1;
else output[i] = 1;
}
}
void BPSKdemapping(short* input, short* output, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] == -1)
output[i] == 0;
else output[i] == 1;
}
}
void QPSKmapping(short* input, Complex* output, int nbits)
{
int i;
for(i = 0; i < nbits; i += 2)
{
if(input[i] == 0 && input[i+1] == 0)
{
output[i].real = -1;
output[i+1].img = -1;
}
else if(input[i] == 0 && input[i+1] == 1)
{
output[i].real = -1;
output[i+1].img = 1;
}
else if(input[i] == 1 && input[i+1] == 0)
{
output[i].real = 1;
output[i+1].img = -1;
}
else
{
output[i].real = 1;
output[i+1].img = 1;
}
}
}
void QPSKdemapping(Complex* input, short* output, int nbits)
{
int i;
for(i = 0; i < nbits; i += 2)
{
if(input[i].real == -1 && input[i+1].img == -1)
{
output[i] = 0;
output[i+1] = 0;
}
else if(input[i].real == -1 && input[i+1].img == 1)
{
output[i] = 0;
output[i+1] = 1;
}
else if(input[i].real == 1 && input[i+1].img == -1)
{
output[i] = 1;
output[i+1] = 0;
}
else
{
output[i] = 1;
output[i+1] = 1;
}
}
}
//Channel Begin
double uniform(double a, double b)
{
double c;
double d;
static int firstcall = 1;
c = b - a;
if(firstcall == 1)
{
srand((unsigned int)time(NULL));
firstcall = 0;
}
d = a + (double)rand() / RAND_MAX * c;
return d;
}
double gauss(double mean, int SNRdb)
{
double dGaussNum;
double x = 0;
int i;
double sigma;
sigma = 1 / pow(10, (double)SNRdb / 10);
for(i = 0;i < 12; i ++)
{
x = x + uniform(0,1);
}
x = x - 6;
dGaussNum = mean + sqrt(sigma) * x;
return dGaussNum;
}
void ChannelModel(Complex R[], Complex S[], int SNRdb)
{
int i;
for (i=0;i<N+L;i++)
{
R[i].real = S[i].real + gauss(0, SNRdb);
R[i].img = S[i].img + gauss(0, SNRdb);
}
}
//Channel End
void deinterleaver(short *input, short *output, int N_CBPS,int N_BPSC)
{
int i;
int t;
int k;
int s;
short first_permutuation[N_CBPS - 1];
s = fmax(N_BPSC/2,1);
for (t = 0; t < N_CBPS; t++)
{
i = s*(t/s) + (t + ((16*t)/N_CBPS)) % s;
first_permutuation[i] = input[t];
}
for(i = 0; i < N_CBPS;i++)
{
k = 16*i - (N_CBPS - 1)*((16*i)/N_CBPS);
output[k] = first_permutuation[i];
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ofdm.h"
int main(int argc, char *argv[])
{
short seed[8];
int bits, i, j, k;
char mode[5], line[1024];
/* Complex twidder[64][64];
FILE *file = fopen("twidder_factor.txt", "r");
i = 0;
while(fgets(line, sizeof(line), file ) != NULL)
{
k = j = 0;
char **result = split(line, "\t");
while(result[k] != NULL)
{
parseComplex(&twidder[i][j], result[k++]);
j++;
}
i++;
}
*/
printf("How many bits do you want to transmit?: ");
scanf("%d", &bits);
short* start_input;
short* scrambler_output;
short* encoder_output;
short* interleaver_output;
short* bpsk_mapper_output;
short* ifft_bpsk_input[64];
Complex* qpsk_mapper_output;
Complex ifft_qpsk_input[64];
start_input = malloc(sizeof(short) * bits);
scrambler_output = malloc(sizeof(short) * bits);
encoder_output = malloc(sizeof(short) * (bits * 2));
interleaver_output = malloc(sizeof(short) * (bits * 2));
bpsk_mapper_output = malloc(sizeof(short) * (bits * 2));
qpsk_mapper_output = malloc(sizeof(Complex) * (bits * 2));
if(qpsk_mapper_output == NULL)
{
fprintf(stderr, "Couldn't allocate that much memory!\n");
return 1;
}
srand(time(NULL));
rbits(seed, 8);
rbits(start_input, bits);
printf("Which modulation type to you want to use? (type BPSK or QPSK): ");
scanf("%s", mode);
if((strcmp(mode, "BPSK") == 0) || (strcmp(mode, "bpsk") == 0))
{
printf("\nSelected modulation type: BPSK\n\n\n");
printf("SCRAMBLER OUTPUT:\n\n");
scrambler(seed, start_input, scrambler_output, bits, 8);
printbinary(scrambler_output, bits);
printf("ENCODER OUTPUT:\n\n");
encoder(scrambler_output, encoder_output, bits);
printbinary(encoder_output, bits*2);
printf("INTERLEAVER OUTPUT:\n\n");
interleaver(encoder_output, interleaver_output, bits, 1);
printbinary(interleaver_output, bits*2);
printf("MAPPER OUTPUT:\n\n");
BPSKmapping(interleaver_output, bpsk_mapper_output, bits*2);
printbinary(bpsk_mapper_output, bits*2);
printf("FIXED-POINT OUTPUT:\n\n");
fixed_point(bpsk_mapper_output, bits*2);
printbinary(bpsk_mapper_output, bits*2);
/*
printf("IFFT OUTPUT:\n\n");
IFFT_BPSK(bpsk_mapper_output, ifft_bpsk_input, twidder, bits*2)
defixed_point(bpsk_mapper_output, bits*2);
printbinary(bpsk_mapper_output, bits*2);
*/ }
else if((strcmp(mode, "QPSK") == 0) || (strcmp(mode, "qpsk") == 0))
{
printf("\nSelected modulation type: QPSK\n\n\n");
printf("SCRAMBLER OUTPUT:\n\n");
scrambler(seed, start_input, scrambler_output, bits, 8);
printbinary(scrambler_output, bits);
printf("ENCODER OUTPUT:\n\n");
encoder(scrambler_output, encoder_output, bits);
printbinary(encoder_output, bits*2);
printf("INTERLEAVER OUTPUT:\n\n");
interleaver(encoder_output, interleaver_output, bits, 2);
printbinary(interleaver_output, bits*2);
printf("MAPPER OUTPUT:\n\n");
QPSKmapping(interleaver_output, qpsk_mapper_output, bits*2);
printcomplex(qpsk_mapper_output, bits*2);
/*
printf("FIXED-POINT OUTPUT:\n\n");
fixed_point_complex(qpsk_mapper_output, bits*2);
printcomplex(qpsk_mapper_output, bits*2);
printf("IFFT OUTPUT:\n\n");
IFFT_QPSK(qpsk_mapper_output, ifft_qpsk_input, twidder, bits*2)
defixed_point(qpsk_mapper_output, bits*2);
printbinary(qpsk_mapper_output, bits*2);
*/ }
else
{
printf("That's an invalid modulation type!\n");
free(start_input);
free(scrambler_output);
free(encoder_output);
free(interleaver_output);
free(bpsk_mapper_output);
free(qpsk_mapper_output);
return 0;
}
free(start_input);
free(scrambler_output);
free(encoder_output);
free(interleaver_output);
free(bpsk_mapper_output);
free(qpsk_mapper_output);
system("PAUSE");
return 0;
}
If you could help me to solve this problem I would be glad. I think there is some kind of linking problem between my library and the main source file.
Thanks in advance.
I guess you are compiling only main.c. You should also include ofdm.c.
$ gcc -Wall main.c ofdm.c -o output
Since you get this error for all your functions, it can't be a typo. My best guess is that you are not linking the two files.
If using gcc, this is done in the following way:
gcc -o main.o -c main.c
gcc -o ofdm.o -c ofdm.c
gcc -o program main.o ofdm.o
Note that -c means it should compile, but not try to create an executable. This means that linking is not done.
Once both files are compiled, you would then link them together.
When you're learning new things, it helps to learn one new thing at a time. Put your source code into version control, then simplify it to get a clean compile.
main.c
#include "ofdm.h"
int main(int argc, char *argv[])
{
return 0;
}
ofdm.c
#include "ofdm.h"
void leftshift(short *bin,short *erg,int shifts, int len)
{
int i;
for(i = 0;i < len - shifts;i++)
{
erg[i] = bin[i + shifts];
}
for(i = len - shifts;i < len;i++)
{
erg[i] = 0;
}
}
ofdm.h
#ifndef OFDM_H_INCLUDED
#define OFDM_H_INCLUDED
void leftshift(short *bin,short *erg,int shifts, int len);
#endif
Then, to compile with gcc . . .
$ gcc -Wall -c ofdm.c
$ gcc -Wall -c main.c
$ gcc -Wall *.o
That should give you a program that does nothing, successfully. Now you can start to build it up again from your version-controlled source.
Add one function at a time.
Edit it to get a clean compile.
Edit it to pass sane tests.
I came here with the same issue while using ESP-IDF as a beginner. What solved this for me was that I just forgot to add all the necessary sources in the idf_component_register function call.
Related
#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
int getCharNum(int a) { return a / (8 * sizeof(char)); }
int getBitNum(int a) { return a % (8 * sizeof(char)); }
int fromCharNum(int a) { return a * 8 * sizeof(char); }
int get2DimI(int a) { return getCharNum(a) / 187500; }
int get2DimJ(int a) { return getCharNum(a) % 187500; }
void rle_compress(char *src, char *dst, int ls, int *ld) {
uint8_t t[129];
int i, j = 0, k = 0, keep;
char out[187500];
t[0] = src[j];
while (j++ < ls) {
t[1] = src[j];
if (t[0] != t[1]) {
i = 1;
if (j < ls)
do
t[++i] = src[++j];
while (j < ls && i < 128 && t[i] != t[i - 1]);
if ((keep = t[i] == t[i - 1]))
--i;
out[k++] = (char)i;
t[0] = t[i];
if (!keep)
continue;
}
i = 2;
do
t[1] = src[++j];
while (++i < 130 && t[0] == t[1]);
out[k++] = i + 125;
out[k++] = t[0];
t[0] = t[1];
}
ld = &k;
dst = out;
}
void rle_extract(char *src, char *dst, int ls) {
int i, j, l = 0, k = 0, max;
char out[187500];
j = 0;
while (k + 2 < ls) {
i = src[k++]; //segfault
j = src[k++];
max = i + (i < 128 ? 1 : -126);
while (max--)
out[l++] = j;
}
dst = out;
return 0;
}
int main(void) {
int32_t n = 0;
scanf("%d", &n);
int32_t a[n];
int32_t b[] = { -1, -1, -1 };
char **count;
count = (char**)malloc(1000 * sizeof(char*));
int count_l[] = { [999] = 0 };
for (int i = 0; i < 1000; ++i) {
count[i] = (char*)malloc(187500 * sizeof(char));
char *temp = NULL;
rle_compress(count[i], temp, 187500, &count_l[i]);
free(count[i]);
count[i] = temp;
}
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
for (int i = 0; i < n; i++) {
char *src = count[get2DimI(a[i]) / 187500];
char dst[187500];
rle_extract(src, dst, count_l[i / 187500]);
dst[get2DimJ(a[i])] ^= 1 << (getBitNum(a[i]));
rle_compress(dst, count[get2DimI(a[i]) / 187500], 187500, &count_l[i]);
}
int32_t mv = 187500000 / (8 * sizeof(char));
int j = 0;
for (int i = 0; i < mv; i++) {
char *src = count[i / 187500];
char dst[187500];
rle_extract(src, dst, count_l[i / 187500]);
int32_t x = dst[i % 187500];
if (x == 0)
continue;
for (int k = 0; k < 8 * sizeof(char); k++) {
if ((x >> (k)) & 1) {
b[j++] = fromCharNum(i) + k;
}
}
//free(dst);
}
int m1 = min(b[0], min(b[1], b[2])),
m3 = max(b[0], max(b[1], b[2])),
m2 = b[0] + b[1] + b[2] - m1 - m3;
printf("%d %d %d", m1, m2, m3);
for (int i = 0; i < 1000; ++i)
free(count[i]);
free(count);
return 0;
}
How to fix this code?
I'm trying to compress byte array (which should compress greatly as n should be <=1500000 and numbers are from 0 to 1.5*10^9), but code gives me segfault on all testing inputs which I've tried. Without compress everything worked like a charm, but needed a lot of memory (and limits are 64MiB).
The code is obscure but there are some major problems:
void rle_extract(char *src, char *dst, int ls) does not take the output buffer from its caller, nor does it return a pointer to it: dst = out; just updates the argument value, not the caller's variable passed as an argument. Furthermore return 0; from a void function is incorrect too.
in any case, rle_extract should not return its local out buffer because it is only defined during the execution of the function and is discarded as soon as the function returns.
You should either pass the buffer as an argument or allocate it locally and return the pointer to the caller.
There might be other problems, there is no explanation for what the code is supposed to do.
I have an implementation of SHA-3 hash algorithm in C, it works correctly with not-empty files, but when I try to get a digest of an empty file, I get the wrong digest.
For example, if hash a file with only "a" letter, I get:
be5215abf72333a73b992dafdf4ab59884b948452e0015cfaddaa0b87a0e4515
But, when I hash empty file, I get
0000000000000000000000000000000000000000000000000000000000000000
I expected:
a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a
(https://en.wikipedia.org/wiki/SHA-3#Examples_of_SHA-3_variants)
Can anyone tell me what is wrong in my implementation?
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define index(x, y) (((x) % 5) + 5 * ((y) % 5))
#define KECCAK_ROUNDS 24
#define Plen 200
typedef unsigned int uint;
const uint64_t round_constants[KECCAK_ROUNDS] =
{
0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000,
0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003,
0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A,
0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
};
/* --------------------------------------------------------------------------- */
static uint64_t
rol(uint64_t a, uint offset)
{
if (offset == 0) {
return a;
}
return (a << offset) | (a >> (64 - offset));
}
static void
theta(uint64_t *A)
{
uint64_t C[5], D[5];
for (uint x = 0; x < 5; ++x) {
C[x] = 0;
for (uint y = 0; y < 5; ++y) {
C[x] ^= A[index(x, y)];
}
}
for (uint x = 0; x < 5; ++x) {
D[x] = rol(C[(x + 1) % 5], 1) ^ C[(x + 4) % 5];
}
for (uint x = 0; x < 5; ++x) {
for (uint y = 0; y < 5; ++y) {
A[index(x, y)] ^= D[x];
}
}
}
static void
rho(uint64_t *A)
{
uint newX, newY, ro[KECCAK_ROUNDS];
ro[index(0, 0)] = 0;
uint x = 1;
uint y = 0;
for (uint t = 0; t < KECCAK_ROUNDS; ++t) {
ro[index(x, y)] = ((t + 1) * (t + 2) / 2) % 64;
newX = (0 * x + 1 * y) % 5;
newY = (2 * x + 3 * y) % 5;
x = newX;
y = newY;
}
for (x = 0; x < 5; ++x) {
for (y = 0; y < 5; ++y) {
A[index(x, y)] = rol(A[index(x, y)], ro[index(x, y)]);
}
}
}
static void
pi(uint64_t *A)
{
uint64_t tempA[25];
for (uint x = 0; x < 5; ++x) {
for (uint y = 0; y < 5; ++y) {
tempA[index(x, y)] = A[index(x, y)];
}
}
for (uint x = 0; x < 5; ++x) {
for (uint y = 0; y < 5; ++y) {
A[index(0 * x + 1 * y, 2 * x + 3 * y)] = tempA[index(x, y)];
}
}
}
static void
chi(uint64_t *A)
{
uint64_t C[5];
for (uint y = 0; y < 5; ++y) {
for (uint x = 0; x < 5; ++x) {
C[x] = A[index(x, y)] ^ ((~A[index(x + 1, y)]) & A[index(x + 2, y)]);
}
for (uint x = 0; x < 5; ++x) {
A[index(x, y)] = C[x];
}
}
}
static void
iota(uint64_t *A, uint indexRound)
{
A[index(0, 0)] ^= round_constants[indexRound];
}
static void
keccakf(void *state)
{
for (uint i = 0; i < KECCAK_ROUNDS; ++i) {
theta(state);
rho(state);
pi(state);
chi(state);
iota(state, i);
}
}
static void
xorin(uint8_t *dest, const uint8_t *src, size_t len)
{
for (size_t i = 0; i < len; ++i) {
dest[i] ^= src[i];
}
}
static void
setout(uint8_t *dest, const uint8_t *src, size_t len)
{
for (size_t i = 0; i < len; ++i) {
dest[i] = src[i];
}
}
/* The sponge-based hash construction. */
static void
hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen, size_t rate, uint8_t delim)
{
if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
return;
}
uint8_t a[Plen] = { 0 /* 0, 0, 0, ... */ };
while (inlen >= rate) {
xorin(a, in, rate);
keccakf(a);
in += rate;
inlen -= rate;
}
a[inlen] ^= delim;
a[rate - 1] ^= 0x80;
xorin(a, in, inlen);
keccakf(a);
while (outlen >= rate) {
setout(out, a, rate);
keccakf(a);
out += rate;
outlen -= rate;
}
setout(out, a, outlen);
memset(a, '\0', Plen);
}
int
sha3_stream (FILE *stream, void *resblock, size_t databitlen)
{
size_t SHA3_BLOCK = databitlen / 8;
size_t bytesread;
uint8_t *in = malloc (databitlen);
if (!in)
return 1;
while ((bytesread = fread(in, sizeof(char), SHA3_BLOCK, stream)) != 0)
hash(resblock, SHA3_BLOCK, in, bytesread, Plen - (databitlen / 4), 0x06);
free(in);
return 0;
}
int main(int argc, char **argv)
{
/* 32 it is SHA3-256 BLOCK */
/* here used 256 bits digest lenght */
for (int i = 1; i < argc; ++i)
{
uint8_t *out = malloc(32);
FILE *fp = fopen(argv[i], "r");
sha3_stream(fp, out, 256);
for (int j = 0; j < 32; ++j)
printf("%02x", out[j]);
printf(" %s\n", argv[i]);
free(out);
}
}
As said user2722968:
"The while-loop in sha3_stream will not execute at all for an empty file, because you are at EOF on the first iteration. Therefor resblock stays all zero; switch to a do-while loop where the EOF-condition is checked after each iteration, not before."
So, correct code is:
bytesread = fread(in, sizeof(char), SHA3_BLOCK, stream);
do {
hash(resblock, SHA3_BLOCK, in, bytesread, Plen - (databitlen / 4), 0x06);
} while ((bytesread = fread(in, sizeof(char), SHA3_BLOCK, stream)) != 0);
Instead wrong:
while ((bytesread = fread(in, sizeof(char), SHA3_BLOCK, stream)) != 0)
hash(resblock, SHA3_BLOCK, in, bytesread, Plen - (databitlen / 4), 0x06);
I am running the c code of Shannon-Fano compression algorithm. The program is compiling better but while executing, I get the segmentation fault (core dump) error. Similar questions have been already answered but I tried most of them but could not get sucess in resolving this error. please help me out.
The program code is:
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
/***********************************************/
int Compress(int* input, int* output, int inputSize);
int main(int argc, char *argv[])
{
char* str = "This is an example for Shannon–Fano coding";
printf("%s",str);
int* originalData = originalData = (int*)str;
int originalDataSize = strlen(str);
int* compressedData = (int*)malloc(originalDataSize * (101 / 100) + 384);
int compressedDataSize = Compress(originalData, compressedData, originalDataSize);
return 0;
}
typedef struct {
int* BytePointer;
int BitPosition;
} BitStream;
typedef struct {
int Symbol;
int Count;
int Code;
int Bits;
} Symbol;
void initBitStream(BitStream* stream, int* buffer)
{
stream->BytePointer = buffer;
stream->BitPosition = 0;
}
void writeBits(BitStream* stream, int x, int bits)
{
int* buffer = stream->BytePointer;
int bit = stream->BitPosition;
int mask = 1 << (bits - 1);
for (int count = 0; count < bits; ++count)
{
*buffer = (*buffer & (0xff ^ (1 << (7 - bit)))) + ((x & mask ? 1 : 0) << (7 - bit));
x <<= 1;
bit = (bit + 1) & 7;
if (!bit)
{
++buffer;
}
}
stream->BytePointer = buffer;
stream->BitPosition = bit;
}
void histogram(int* input, Symbol* sym, int size)
{
Symbol temp;
int i, swaps;
for (i = 0; i < 256; ++i)
{
sym[i].Symbol = i;
sym[i].Count = 0;
sym[i].Code = 0;
sym[i].Bits = 0;
}
for (i = size; i; --i)
{
sym[*input++].Count++;
}
do
{
swaps = 0;
for (i = 0; i < 255; ++i)
{
if (sym[i].Count < sym[i + 1].Count)
{
temp = sym[i];
sym[i] = sym[i + 1];
sym[i + 1] = temp;
swaps = 1;
}
}
} while (swaps);
}
void makeTree(Symbol* sym, BitStream* stream, int code, int bits, int first, int last)
{
int i, size, sizeA, sizeB, lastA, firstB;
if (first == last)
{
writeBits(stream, 1, 1);
writeBits(stream, sym[first].Symbol, 8);
sym[first].Code = code;
sym[first].Bits = bits;
return;
}
else
{
writeBits(stream, 0, 1);
}
size = 0;
for (i = first; i <= last; ++i)
{
size += sym[i].Count;
}
sizeA = 0;
for (i = first; sizeA < ((size + 1) >> 1) && i < last; ++i)
{
sizeA += sym[i].Count;
}
if (sizeA > 0)
{
writeBits(stream, 1, 1);
lastA = i - 1;
makeTree(sym, stream, (code << 1) + 0, bits + 1, first, lastA);
}
else
{
writeBits(stream, 0, 1);
}
sizeB = size - sizeA;
if (sizeB > 0)
{
writeBits(stream, 1, 1);
firstB = i;
makeTree(sym, stream, (code << 1) + 1, bits + 1, firstB, last);
}
else
{
writeBits(stream, 0, 1);
}
}
int Compress(int* input, int* output, int inputSize)
{
Symbol sym[256], temp;
BitStream stream;
int i, totalBytes, swaps, symbol, lastSymbol;
if (inputSize < 1)
return 0;
initBitStream(&stream, output);
histogram(input, sym, inputSize);
for (lastSymbol = 255; sym[lastSymbol].Count == 0; --lastSymbol);
if (lastSymbol == 0)
++lastSymbol;
makeTree(sym, &stream, 0, 0, 0, lastSymbol);
do
{
swaps = 0;
for (i = 0; i < 255; ++i)
{
if (sym[i].Symbol > sym[i + 1].Symbol)
{
temp = sym[i];
sym[i] = sym[i + 1];
sym[i + 1] = temp;
swaps = 1;
}
}
} while (swaps);
for (i = 0; i < inputSize; ++i)
{
symbol = input[i];
writeBits(&stream, sym[symbol].Code, sym[symbol].Bits);
}
totalBytes = (int)(stream.BytePointer - output);
if (stream.BitPosition > 0)
{
++totalBytes;
}
return totalBytes;
}
I tried to implement C code for Wavelet transform in FPGA (Zynq ZC 702) but the code get stuck and this is because of memory problem so I should optimize my code but I don't know how.
Can anyone please give me some ideas how to do that ?
This is the main of the code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "wavemin.h"
#include "waveaux.h"
#include "waveaux.c"
#include "wavemin.c"
int main() {
printf("Hello World1 \n\r");
wave_object obj;
wt_object wt;
float *inp, *out;
int N, i, J,k;
float temp[1280] = {};
char *name = "db4";
obj = wave_init(name);
printf("Hello World2 \n\r");
N = 1280;
inp = (float*)malloc(sizeof(float) * N);
out = (float*)malloc(sizeof(float) * N);
//wmean = mean(temp, N);
for (i = 0; i < N; ++i) {
inp[i] = temp[i];
printf("Hello World3 \n\r");
//printf("%g \n", inp[i]);
}
J = 4; //Decomposition Levels
wt = wt_init(obj, "dwt", N, J); // Initialize the wavelet transform object
printf("Hello World4 \n\r");
setDWTExtension(wt, "sym"); // Options are "per" and "sym". Symmetric is the default option
printf("Hello World5 \n\r");
setWTConv(wt, "direct");
printf("Hello World6 \n\r");
dwt(wt, inp); // Perform DWT
printf("Hello World7 \n\r");
//getDWTAppx(wt, out, wt->length[0]);
// printf("Approximation Coefficients Level 1 \n");
// for (i = 0; i < wt->length[0]; ++i) {
// printf("%g ", out[i]);
// }
// printf("\n\n");
for (k = 1; k <= J; ++k) {
getDWTDetail(wt, out, wt->length[k], k);
printf("Detail Coefficients Level %d Length %d \n",
k, wt - length[k]);
for (i = 0; i < wt->length[k]; ++i) {
printf("%g ", out[i]);
}
printf("\n\n");
}
wt_summary(wt);// Prints the full summary.
printf("Hello World8 \n\r");
wave_free(obj);
wt_free(wt);
free(inp);
free(out);
return 0;
}
The other part of the code where there is the function used in the main function:
#include "wavemin.h"
wave_object wave_init(char *wname) {
wave_object obj = NULL;
int retval;
retval = 0;
if (wname != NULL) {
retval = filtlength(wname);
}
obj = (wave_object)malloc(sizeof(struct wave_set) + sizeof(float) * 4 *
retval);
obj->filtlength = retval;
obj->lpd_len = obj->hpd_len = obj->lpr_len = obj->hpr_len = obj->filtlength;
strcpy(obj->wname, wname);
if (wname != NULL) {
filtcoef(wname, obj->params, obj->params + retval, obj->params + 2 *
retval, obj->params + 3 * retval);
}
obj->lpd = &obj->params[0];
obj->hpd = &obj->params[retval];
obj->lpr = &obj->params[2 * retval];
obj->hpr = &obj->params[3 * retval];
return obj;
}
wt_object wt_init(wave_object wave, char *method, int siglength, int J) {
int size, i, MaxIter;
wt_object obj = NULL;
size = wave->filtlength;
MaxIter = wmaxiter(siglength, size);
if (!strcmp(method, "dwt") || !strcmp(method, "DWT")) {
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(float) *
(siglength + 2 * J * (size + 1)));
obj->outlength = siglength + 2 * J * (size + 1); // Default
strcpy(obj->ext, "sym"); // Default
}
obj->wave = wave;
obj->siglength = siglength;
obj->J = J;
obj->MaxIter = MaxIter;
strcpy(obj->method, method);
if (siglength % 2 == 0) {
obj->even = 1;
}
else {
obj->even = 0;
}
strcpy(obj->cmethod, "direct"); // Default
obj->cfftset = 0;
obj->lenlength = J + 2;
obj->output = &obj->params[0];
if (!strcmp(method, "dwt") || !strcmp(method, "DWT")) {
for (i = 0; i < siglength + 2 * J * (size + 1); ++i) {
obj->params[i] = 0.0;
}
}
//wave_summary(obj->wave);
return obj;
}
static void dwt_sym(wt_object wt, float *inp, int N, float *cA, int len_cA,
float *cD, int len_cD) {
int i, l, t, len_avg;
len_avg = wt->wave->lpd_len;
for (i = 0; i < len_cA; ++i) {
t = 2 * i + 1;
cA[i] = 0.0;
cD[i] = 0.0;
for (l = 0; l < len_avg; ++l) {
if ((t - l) >= 0 && (t - l) < N) {
cA[i] += wt->wave->lpd[l] * inp[t - l];
cD[i] += wt->wave->hpd[l] * inp[t - l];
printf("world1 \n\r");
}
else if ((t - l) < 0) {
cA[i] += wt->wave->lpd[l] * inp[-t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[-t + l - 1];
printf("world2 \n\r");
}
else if ((t - l) >= N) {
cA[i] += wt->wave->lpd[l] * inp[2 * N - t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[2 * N - t + l - 1];
printf("world3 \n\r");
}
}
}
}
void dwt(wt_object wt, float *inp) {
int i, J, temp_len, iter, N, lp;
int len_cA;
float *orig, *orig2;
temp_len = wt->siglength;
J = wt->J;
wt->length[J + 1] = temp_len;
wt->outlength = 0;
wt->zpad = 0;
orig = (float*)malloc(sizeof(float) * temp_len);
orig2 = (float*)malloc(sizeof(float) * temp_len);
for (i = 0; i < wt->siglength; ++i) {
orig[i] = inp[i];
printf("Hello1 \n\r");
}
if (wt->zpad == 1) {
orig[temp_len - 1] = orig[temp_len - 2];
printf("Hello2 \n\r");
}
N = temp_len;
lp = wt->wave->lpd_len;
if (!strcmp(wt->ext, "sym")) {
//printf("\n YES %s \n", wt->ext);
i = J;
while (i > 0) {
N = N + lp - 2;
N = (int)ceil((float)N / 2.0);
wt->length[i] = N;
wt->outlength += wt->length[i];
i--;
}
wt->length[0] = wt->length[1];
wt->outlength += wt->length[0];
N = wt->outlength;
printf("Hello3 \n\r");
for (iter = 0; iter < J; ++iter) {
len_cA = wt->length[J - iter];
N -= len_cA;
dwt_sym(wt, orig, temp_len, orig2, len_cA, wt->params + N, len_cA);
temp_len = wt->length[J - iter];
printf("Hello4 \n\r");
if (iter == J - 1) {
for (i = 0; i < len_cA; ++i) {
wt->params[i] = orig2[i];
printf("Hello5 \n\r");
}
} else {
for (i = 0; i < len_cA; ++i) {
orig[i] = orig2[i];
printf("Hello6 \n\r");
}
}
}
} else {
printf("Signal extension can be either per or sym");
exit(-1);
}
free(orig);
free(orig2);
}
void setDWTExtension(wt_object wt, char *extension) {
if (!strcmp(extension, "sym")) {
strcpy(wt->ext, "sym");
} else {
printf("Signal extension can be either per or sym");
exit(-1);
}
}
void setWTConv(wt_object wt, char *cmethod) {
if (!strcmp(cmethod, "direct")) {
strcpy(wt->cmethod, "direct");
}
}
void getDWTDetail(wt_object wt, float *detail, int N, int level) {
/*
returns Detail coefficents at the jth level where j = 1,2,.., J
and Wavelet decomposition is stored as
[A(J) D(J) D(J-1) ..... D(1)] in wt->output vector
Use getDWTAppx() to get A(J)
Level 1 : Length of D(J), ie N, is stored in wt->length[1]
Level 2 :Length of D(J-1), ie N, is stored in wt->length[2]
....
Level J : Length of D(1), ie N, is stored in wt->length[J]
*/
int i, iter, J;
J = wt->J;
if (level > J) {
printf("The decomposition only has %d levels", J);
}
iter = wt->length[0];
for (i = 1; i < level; ++i) {
iter += wt->length[i];
}
for (i = 0; i < N; ++i) {
detail[i] = wt->output[i + iter];
}
}
void getDWTAppx(wt_object wt, float *appx, int N) {
/*
Wavelet decomposition is stored as
[A(J) D(J) D(J-1) ..... D(1)] in wt->output vector
Length of A(J) , N = wt->length[0]
*/
int i;
for (i = 0; i < N; ++i) {
appx[i] = wt->output[i];
}
}
void wt_summary(wt_object wt) {
int i;
int J, t;
J = wt->J;
printf("Wavelet Coefficients are contained in vector : %s \n", "output");
printf("\n");
printf("Approximation Coefficients \n");
printf("Level %d Access : output[%d] Length : %d \n",
1, 0, wt->length[0]);
printf("\n");
printf("Detail Coefficients \n");
t = wt->length[0];
for (i = 0; i < J; ++i) {
printf("Level %d Access : output[%d] Length : %d \n",
i + 1, t, wt->length[i + 1]);
t += wt->length[i + 1];
}
printf("\n");
}
void wave_free(wave_object object) {
free(object);
}
void wt_free(wt_object object) {
free(object);
}
enter image description here
In your code
Always check if malloc has returned non NULL value
Check your stack and heap settings in the linker file as you declare massive local variables and do a lots of mallocs - I suspect the (nomen omen)stack overflow, or failed mallocs.
Is it a bare metal program or you run it under some kind of OS?
Just for a matter of style and concision, I would rewrite this:
if (siglength % 2 == 0) {
obj->even = 1;
}
else {
obj->even = 0;
}
Into the following code:
obj->even = !(siglength % 2);
Or, alternatively:
obj->even = (siglength % 2) ? 0 : 1;
Also, I think there is room for optimization in this function:
static void dwt_sym(wt_object wt, float *inp, int N, float *cA, int len_cA,
float *cD, int len_cD) {
int i, l, t, len_avg;
len_avg = wt->wave->lpd_len;
for (i = 0; i < len_cA; ++i) {
t = 2 * i + 1;
cA[i] = 0.0;
cD[i] = 0.0;
for (l = 0; l < len_avg; ++l) {
if ((t - l) >= 0 && (t - l) < N) {
cA[i] += wt->wave->lpd[l] * inp[t - l];
cD[i] += wt->wave->hpd[l] * inp[t - l];
printf("world1 \n\r");
}
else if ((t - l) < 0) {
cA[i] += wt->wave->lpd[l] * inp[-t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[-t + l - 1];
printf("world2 \n\r");
}
else if ((t - l) >= N) {
cA[i] += wt->wave->lpd[l] * inp[2 * N - t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[2 * N - t + l - 1];
printf("world3 \n\r");
}
}
}
}
First, you are always referring to t - 1 and never t itself, so why not have:
t = 2 * i;
And, I can guess that a lot of computation can be placed outside of the inner loop... If you want to optimize, there are many good candidate here.
One last word about optimization!
You should first profile your software and see where you spend the most time before thinking about optimization. You cannot optimize "in the air" without knowing where your software does really struggle. Consider using gprof.
PS: You should never ever use the letter l (ell) as a variable... it is way to close from the number 1 (one). Consider changing this is also, it can improve the reading.
I want to implement cryptography algorithms. So I need a suitable data type to handle integers with a lot of digits.
Many recent languages, such as Java, Python and Ruby provide native ways to do this. However, I'm programming in C, and I was wondering what is the best way and easiest way to implement elementary operations there.
I would like to write it without any external library. I thought about two options:
Using an array of char (like strings, that would be good for encryption/decryption keys)
Using an array of bits (I don't know how to do it, but I think this would be compiler-dependant)
What would you do?
The (to me) obvious choice would be GMP whose main developer, Torbjörn Granlund, was a member of the Swedish five man team that won the Simon Singh "Cipher Challenge" in 2000.
According to the website the code can be used to calculate 1000000000 digits of pi in 1957 seconds on an AMD Phenom II # 3.2 GHz.
The code has been developed since 1991.
I would first off highly suggest using an already existing library.
However, I have done this before in the past as an experiment. I choose option 2. Representing a value like "10000000002000000000" as
int array[2] = { 1000000000, 2000000000 }
and performing operations and carry values one int at a time. Not very efficient, but functionally sound.
If you are interested in Cryptography, then everything has to be correct. Either you spend many months writing and testing and testing and testing... your own big number arithmetic functions, or you use an existing library.
It is difficult enough getting crypto to work correctly when you know that the methods you are using are correct. It is almost impossible if the methods you are using have subtle errors.
For crypto use GMP, and concentrate on the crypto.
If you want to write your own large number arithmetic package, then by all means do so. I have done the same myself and it is an interesting and useful experience. But don't use your own work for anything critical.
It will be easier to deal with an array of characters. Its a good idea to devise your own class (/datatype), defining functions to deal with the all arithmetic operations for future use. You could use this one designed by ACRush for reference.
the variable in main function can Store even 100 factorial in c++
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <map>
#include <functional>
#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <stack>
#include <queue>
#include <deque>
#include <limits>
#include <cmath>
#include <numeric>
#include <set>
using namespace std;
//template for BIGINIT
// base and base_digits must be consistent
const int base = 10;
const int base_digits = 1;
struct bigint {
vector<int> a;
int sign;
bigint() :
sign(1) {
}
bigint(long long v) {
*this = v;
}
bigint(const string &s) {
read(s);
}
void operator=(const bigint &v) {
sign = v.sign;
a = v.a;
}
void operator=(long long v) {
sign = 1;
if (v < 0)
sign = -1, v = -v;
for (; v > 0; v = v / base)
a.push_back(v % base);
}
bigint operator+(const bigint &v) const {
if (sign == v.sign) {
bigint res = v;
for (int i = 0, carry = 0; i < (int) max(a.size(), v.a.size()) || carry; ++i) {
if (i == (int) res.a.size())
res.a.push_back(0);
res.a[i] += carry + (i < (int) a.size() ? a[i] : 0);
carry = res.a[i] >= base;
if (carry)
res.a[i] -= base;
}
return res;
}
return *this - (-v);
}
bigint operator-(const bigint &v) const {
if (sign == v.sign) {
if (abs() >= v.abs()) {
bigint res = *this;
for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) {
res.a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0);
carry = res.a[i] < 0;
if (carry)
res.a[i] += base;
}
res.trim();
return res;
}
return -(v - *this);
}
return *this + (-v);
}
void operator*=(int v) {
if (v < 0)
sign = -sign, v = -v;
for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) {
if (i == (int) a.size())
a.push_back(0);
long long cur = a[i] * (long long) v + carry;
carry = (int) (cur / base);
a[i] = (int) (cur % base);
//asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base));
}
trim();
}
bigint operator*(int v) const {
bigint res = *this;
res *= v;
return res;
}
friend pair<bigint, bigint> divmod(const bigint &a1, const bigint &b1) {
int norm = base / (b1.a.back() + 1);
bigint a = a1.abs() * norm;
bigint b = b1.abs() * norm;
bigint q, r;
q.a.resize(a.a.size());
for (int i = a.a.size() - 1; i >= 0; i--) {
r *= base;
r += a.a[i];
int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
int d = ((long long) base * s1 + s2) / b.a.back();
r -= b * d;
while (r < 0)
r += b, --d;
q.a[i] = d;
}
q.sign = a1.sign * b1.sign;
r.sign = a1.sign;
q.trim();
r.trim();
return make_pair(q, r / norm);
}
bigint operator/(const bigint &v) const {
return divmod(*this, v).first;
}
bigint operator%(const bigint &v) const {
return divmod(*this, v).second;
}
void operator/=(int v) {
if (v < 0)
sign = -sign, v = -v;
for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) {
long long cur = a[i] + rem * (long long) base;
a[i] = (int) (cur / v);
rem = (int) (cur % v);
}
trim();
}
bigint operator/(int v) const {
bigint res = *this;
res /= v;
return res;
}
int operator%(int v) const {
if (v < 0)
v = -v;
int m = 0;
for (int i = a.size() - 1; i >= 0; --i)
m = (a[i] + m * (long long) base) % v;
return m * sign;
}
void operator+=(const bigint &v) {
*this = *this + v;
}
void operator-=(const bigint &v) {
*this = *this - v;
}
void operator*=(const bigint &v) {
*this = *this * v;
}
void operator/=(const bigint &v) {
*this = *this / v;
}
bool operator<(const bigint &v) const {
if (sign != v.sign)
return sign < v.sign;
if (a.size() != v.a.size())
return a.size() * sign < v.a.size() * v.sign;
for (int i = a.size() - 1; i >= 0; i--)
if (a[i] != v.a[i])
return a[i] * sign < v.a[i] * sign;
return false;
}
bool operator>(const bigint &v) const {
return v < *this;
}
bool operator<=(const bigint &v) const {
return !(v < *this);
}
bool operator>=(const bigint &v) const {
return !(*this < v);
}
bool operator==(const bigint &v) const {
return !(*this < v) && !(v < *this);
}
bool operator!=(const bigint &v) const {
return *this < v || v < *this;
}
void trim() {
while (!a.empty() && !a.back())
a.pop_back();
if (a.empty())
sign = 1;
}
bool isZero() const {
return a.empty() || (a.size() == 1 && !a[0]);
}
bigint operator-() const {
bigint res = *this;
res.sign = -sign;
return res;
}
bigint abs() const {
bigint res = *this;
res.sign *= res.sign;
return res;
}
long long longValue() const {
long long res = 0;
for (int i = a.size() - 1; i >= 0; i--)
res = res * base + a[i];
return res * sign;
}
friend bigint gcd(const bigint &a, const bigint &b) {
return b.isZero() ? a : gcd(b, a % b);
}
friend bigint lcm(const bigint &a, const bigint &b) {
return a / gcd(a, b) * b;
}
void read(const string &s) {
sign = 1;
a.clear();
int pos = 0;
while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) {
if (s[pos] == '-')
sign = -sign;
++pos;
}
for (int i = s.size() - 1; i >= pos; i -= base_digits) {
int x = 0;
for (int j = max(pos, i - base_digits + 1); j <= i; j++)
x = x * 10 + s[j] - '0';
a.push_back(x);
}
trim();
}
friend istream& operator>>(istream &stream, bigint &v) {
string s;
stream >> s;
v.read(s);
return stream;
}
friend ostream& operator<<(ostream &stream, const bigint &v) {
if (v.sign == -1)
stream << '-';
stream << (v.a.empty() ? 0 : v.a.back());
for (int i = (int) v.a.size() - 2; i >= 0; --i)
stream << setw(base_digits) << setfill('0') << v.a[i];
return stream;
}
static vector<int> convert_base(const vector<int> &a, int old_digits, int new_digits) {
vector<long long> p(max(old_digits, new_digits) + 1);
p[0] = 1;
for (int i = 1; i < (int) p.size(); i++)
p[i] = p[i - 1] * 10;
vector<int> res;
long long cur = 0;
int cur_digits = 0;
for (int i = 0; i < (int) a.size(); i++) {
cur += a[i] * p[cur_digits];
cur_digits += old_digits;
while (cur_digits >= new_digits) {
res.push_back(int(cur % p[new_digits]));
cur /= p[new_digits];
cur_digits -= new_digits;
}
}
res.push_back((int) cur);
while (!res.empty() && !res.back())
res.pop_back();
return res;
}
typedef vector<long long> vll;
static vll karatsubaMultiply(const vll &a, const vll &b) {
int n = a.size();
vll res(n + n);
if (n <= 32) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
res[i + j] += a[i] * b[j];
return res;
}
int k = n >> 1;
vll a1(a.begin(), a.begin() + k);
vll a2(a.begin() + k, a.end());
vll b1(b.begin(), b.begin() + k);
vll b2(b.begin() + k, b.end());
vll a1b1 = karatsubaMultiply(a1, b1);
vll a2b2 = karatsubaMultiply(a2, b2);
for (int i = 0; i < k; i++)
a2[i] += a1[i];
for (int i = 0; i < k; i++)
b2[i] += b1[i];
vll r = karatsubaMultiply(a2, b2);
for (int i = 0; i < (int) a1b1.size(); i++)
r[i] -= a1b1[i];
for (int i = 0; i < (int) a2b2.size(); i++)
r[i] -= a2b2[i];
for (int i = 0; i < (int) r.size(); i++)
res[i + k] += r[i];
for (int i = 0; i < (int) a1b1.size(); i++)
res[i] += a1b1[i];
for (int i = 0; i < (int) a2b2.size(); i++)
res[i + n] += a2b2[i];
return res;
}
bigint operator*(const bigint &v) const {
vector<int> a6 = convert_base(this->a, base_digits, 6);
vector<int> b6 = convert_base(v.a, base_digits, 6);
vll a(a6.begin(), a6.end());
vll b(b6.begin(), b6.end());
while (a.size() < b.size())
a.push_back(0);
while (b.size() < a.size())
b.push_back(0);
while (a.size() & (a.size() - 1))
a.push_back(0), b.push_back(0);
vll c = karatsubaMultiply(a, b);
bigint res;
res.sign = sign * v.sign;
for (int i = 0, carry = 0; i < (int) c.size(); i++) {
long long cur = c[i] + carry;
res.a.push_back((int) (cur % 1000000));
carry = (int) (cur / 1000000);
}
res.a = convert_base(res.a, 6, base_digits);
res.trim();
return res;
}
};
//use : bigint var;
//template for biginit over
int main()
{
bigint var=10909000890789;
cout<<var;
return 0;
}