My decimal to binary conversion is printing out extra numbers - c

So I'm very new to C, and I'm having trouble with my decimal to binary conversions.
I'm trying to convert 2 numbers - "205" and "171" too binary and put them both in separate arrays, and its working - sort of. See they both convert properly, but they both have three extra "1"s trailing them.
For example, when I use "printf" to see what is in the x array, it is "11001101111" instead of "11001101". The same happens with the y array.
Here's the program so far (I tried to annotate it to make it as clear as possible).
Note: I commented out the "printf" for the y array, but you can switch them out if you want.
int inputx = 205;
int inputy = 171;
//scanf("%d %d", &inputx, &inputy); //
int x[16] = {};
int y[16] = {};
//declaring variables for x conversion
int i = 0;
int d1 = 0;
int c = 0;
int a = 0;
int number1[16] = {};
//converting inputx from decimal into binary
while (inputx != 0){
i = i+1;
d1 = inputx % 2;
inputx = inputx / 2;
c++;
number1[c]=d1;
}//end while
//since the binary array is in reverse, this loop fixes it
for(a = 0; a < c; a = a + 1 ){
x[a]=number1[c-a];
printf("%d", x[a]); //printf just for testing
}//end for
//declaring variables for y conversion
i = 0;
d1 = 0;
int c2 = 0;
a = 0;
int number2[16] = {};
//converting inputy from decimal to binary
while (inputy != 0){
i = i+1;
d1 = inputy % 2;
inputy = inputy / 2;
c2++;
number2[c2]=d1;
}//end while
//since the binary array is in reverse, this loop fixes it
for(a = 0; a < c2; a = a + 1 ){
y[a] = number2[c2-a];
// printf("%d", y[a]); //printf just for testing
}//end for
Any help is appreciated!

Related

I am trying to improve the performance speed of my cross-correlation algorithm. What things can I do to make my C code run faster?

I created a cross-correlation algorithm, and I am trying to maximize its performance by reducing the time it takes for it to run. First of all, I reduced the number of function calls within the "crossCorrelationV2" function. Second, I created several macros at the top of the program for constants. Third, I reduced the number of loops that are inside the "crossCorrelationV2" function. The code that you see is the most recent code that I have.
Are there any other methods I can use to try and reduce the processing time of my code?
Let's assume that I am only focused on the functions "crossCorrelationV2" and "createAnalyzingWave".
I would be glad for any advice, whether in general about programming or pertaining to those two specific functions; I am a beginner programmer. Thanks.
#include <stdio.h>
#include <stdlib.h>
#define ARRAYSIZE 4096
#define PULSESNUMBER 16
#define DATAFREQ 1300
// Print the contents of the array onto the console.
void printArray(double array[], int size){
int k;
for (k = 0; k < size; k++){
printf("%lf ", array[k]);
}
printf("\n");
}
// Creates analyzing square wave. This square wave has unity (1) magnitude.
// The number of high values in each period is determined by high values = (analyzingT/2) / time increment
void createAnalyzingWave(double analyzingFreq, double wave[]){
int highValues = (1 / analyzingFreq) * 0.5 / ((PULSESNUMBER * (1 / DATAFREQ) / ARRAYSIZE));
int counter = 0;
int p;
for(p = 1; p <= ARRAYSIZE; p++){
if ((counter % 2) == 0){
wave[p - 1] = 1;
} else{
wave[p - 1] = 0;
}
if (p % highValues == 0){
counter++;
}
}
}
// Creates data square wave (for testing purposes, for the real implementation actual ADC data will be used). This
// square wave has unity magnitude.
// The number of high values in each period is determined by high values = array size / (2 * number of pulses)
void createDataWave(double wave[]){
int highValues = ARRAYSIZE / (2 * PULSESNUMBER);
int counter = 0;
int p;
for(p = 0; p < ARRAYSIZE; p++){
if ((counter % 2) == 0){
wave[p] = 1;
} else{
wave[p] = 0;
}
if ((p + 1) % highValues == 0){
counter++;
}
}
}
// Finds the average of all the values inside an array
double arrayAverage(double array[], int size){
int i;
double sum = 0;
// Same thing as for(i = 0; i < arraySize; i++)
for(i = size; i--; ){
sum = array[i] + sum;
}
return sum / size;
}
// Cross-Correlation algorithm
double crossCorrelationV2(double dataWave[], double analyzingWave[]){
int bigArraySize = (2 * ARRAYSIZE) - 1;
// Expand analyzing array into array of size 2arraySize-1
int lastArrayIndex = ARRAYSIZE - 1;
int lastBigArrayIndex = 2 * ARRAYSIZE - 2; //bigArraySize - 1; //2 * arraySize - 2;
double bigAnalyzingArray[bigArraySize];
int i;
int b;
// Set first few elements of the array equal to analyzingWave
// Set remainder of big analyzing array to 0
for(i = 0; i < ARRAYSIZE; i++){
bigAnalyzingArray[i] = analyzingWave[i];
bigAnalyzingArray[i + ARRAYSIZE] = 0;
}
double maxCorrelationValue = 0;
double currentCorrelationValue;
// "Beginning" of correlation algorithm proper
for(i = 0; i < bigArraySize; i++){
currentCorrelationValue = 0;
for(b = lastBigArrayIndex; b > 0; b--){
if (b >= lastArrayIndex){
currentCorrelationValue = dataWave[b - lastBigArrayIndex / 2] * bigAnalyzingArray[b] + currentCorrelationValue;
}
bigAnalyzingArray[b] = bigAnalyzingArray[b - 1];
}
bigAnalyzingArray[0] = 0;
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
}
return maxCorrelationValue;
}
int main(){
int samplesNumber = 25;
double analyzingFreq = 1300;
double analyzingWave[ARRAYSIZE];
double dataWave[ARRAYSIZE];
createAnalyzingWave(analyzingFreq, analyzingWave);
//createDataWave(arraySize, pulsesNumber, dataWave);
double maximumCorrelationArray[samplesNumber];
int i;
for(i = 0; i < samplesNumber; i++){
createDataWave(dataWave);
maximumCorrelationArray[i] = crossCorrelationV2(dataWave, analyzingWave);
}
printf("Average of the array values: %lf\n", arrayAverage(maximumCorrelationArray, samplesNumber));
return 0;
}
The first point is that you are explicitly shifting the analizingData array, this way you are required twice as much memory and moving the items is about 50% of your time. In a test here using crossCorrelationV2 takes 4.1 seconds, with the implementation crossCorrelationV3 it runs in ~2.0 seconds.
The next thing is that you are spending time multiplying by zero on the padded array, removing that, and also removing the padding, and simplifying the indices we end with crossCorrelationV4 that makes the program to run in ~1.0 second.
// Cross-Correlation algorithm
double crossCorrelationV3(double dataWave[], double analyzingWave[]){
int bigArraySize = (2 * ARRAYSIZE) - 1;
// Expand analyzing array into array of size 2arraySize-1
int lastArrayIndex = ARRAYSIZE - 1;
int lastBigArrayIndex = 2 * ARRAYSIZE - 2; //bigArraySize - 1; //2 * arraySize - 2;
double bigAnalyzingArray[bigArraySize];
int i;
int b;
// Set first few elements of the array equal to analyzingWave
// Set remainder of big analyzing array to 0
for(i = 0; i < ARRAYSIZE; i++){
bigAnalyzingArray[i] = analyzingWave[i];
bigAnalyzingArray[i + ARRAYSIZE] = 0;
}
double maxCorrelationValue = 0;
double currentCorrelationValue;
// "Beginning" of correlation algorithm proper
for(i = 0; i < bigArraySize; i++){
currentCorrelationValue = 0;
// Instead of checking if b >= lastArrayIndex inside the loop I use it as
// a stopping condition.
for(b = lastBigArrayIndex; b >= lastArrayIndex; b--){
// instead of shifting bitAnalizing[b] = bigAnalyzingArray[b-1] every iteration
// I simply use bigAnalizingArray[b-i]
currentCorrelationValue = dataWave[b - lastBigArrayIndex / 2] * bigAnalyzingArray[b - i] + currentCorrelationValue;
}
bigAnalyzingArray[0] = 0;
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
}
return maxCorrelationValue;
}
// Cross-Correlation algorithm
double crossCorrelationV4(double dataWave[], double analyzingWave[]){
int bigArraySize = (2 * ARRAYSIZE) - 1;
// Expand analyzing array into array of size 2arraySize-1
int lastArrayIndex = ARRAYSIZE - 1;
int lastBigArrayIndex = 2 * ARRAYSIZE - 2; //bigArraySize - 1; //2 * arraySize - 2;
// I will not allocate the bigAnalizingArray here
// double bigAnalyzingArray[bigArraySize];
int i;
int b;
// I will not copy the analizingWave to bigAnalyzingArray
// for(i = 0; i < ARRAYSIZE; i++){
// bigAnalyzingArray[i] = analyzingWave[i];
// bigAnalyzingArray[i + ARRAYSIZE] = 0;
// }
double maxCorrelationValue = 0;
double currentCorrelationValue;
// Compute the correlation by symmetric paris
// the idea here is to simplify the indices of the inner loops since
// they are computed more times.
for(i = 0; i < lastArrayIndex; i++){
currentCorrelationValue = 0;
for(b = lastArrayIndex - i; b >= 0; b--){
// instead of shifting bitAnalizing[b] = bigAnalyzingArray[b-1] every iteration
// I simply use bigAnalizingArray[b-i]
currentCorrelationValue += dataWave[b] * analyzingWave[b + i];
}
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
if(i != 0){
currentCorrelationValue = 0;
// Correlate shifting to the other side
for(b = lastArrayIndex - i; b >= 0; b--){
// instead of shifting bitAnalizing[b] = bigAnalyzingArray[b-1] every iteration
// I simply use bigAnalizingArray[b-i]
currentCorrelationValue += dataWave[b + i] * analyzingWave[b];
}
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
}
}
return maxCorrelationValue;
}
If you want more optimization you can unroll some iterations of the loop and enable some compiler optimizations like vector extension.

Convert int to bytes array in c

I would like to convert an int to a char[4] where each byte in the char[4] contains a decimal value of 2. So in the following example:
int p = 2999999;
Convert p to the array that is identical to k where k is constructed via:
char k[4];
k[0] = 2;
k[1] = 99;
k[2] = 99;
k[3] = 99;
How can I do this in C?
Thanks in advance!
It's strange problem for me but OK. here's what I would have done:
Copy value of p so that it can be used later (I assume that this conversion doesn't intend to change its value).
Use modulo operation to get 2 last digits
cut down the copy of p to be able to read next two digits.
So complete answer is:
#include <stdio.h>
int main()
{
int p = 2999999;
char k[4];
int p_copy = p;
int i;
for(i = 3; i >=0; i--)
{
k[i] = p_copy % 100;
p_copy /= 100;
}
for(i = 0; i < 4; i++)
printf("k[%d]: %d\n",i, k[i]);
return 0;
}
And for sanity the output:
gonczor#wiktor-papu:~/tmp$ gcc test.c -o test
gonczor#wiktor-papu:~/tmp$ ./test
k[0]: 2
k[1]: 99
k[2]: 99
k[3]: 99
for (i =4; i--; k[i] = p % 100, p /= 100);

C convert two digits to one integer

How can I convert a two digits from array to one integer into a new array?
Example: 1245678933658 to [12,45,67,89,33,65,80] add 0 to the last if its an odd.
My try was:
new_array[i]=digits[i]*10+digits[i++]*10/10;
Does it have to be a "one-liner", or would a more readable code also be allowed? Try the following:
const char* digits = "12456789336581";
int digitIndex=0;
int numbers[100];
int currentNumberIndex = 0;
int currentNumber = 0;
while (digits[digitIndex]) {
currentNumber *=10;
currentNumber += digits[digitIndex] - '0';
digitIndex++;
if ( (digitIndex)%2 == 0) // two digits handled?
{
numbers[currentNumberIndex++] = currentNumber;
currentNumber = 0;
}
}
// handle the case that last number contained just one digit:
if (digitIndex%2) {
currentNumber *=10;
numbers[currentNumberIndex++] = currentNumber;
}
for (int i=0; i < currentNumberIndex; i++)
printf("number[%d]: %d\n", i, numbers[i]);

Join separate integer values to form a whole number

The thing I am trying to achieve is given by the following code:
int a = 2, b = 7, c = 5, d = 0, e = 9;
int x = 27509; /* aka a + b + c + d + e */
What would be a way to do this?
You can try this:
int nums[5] = {2,7,5,0,9};
long long sum = 0;
for (int i=0; i<5; ++i)
sum = sum * 10 + nums[i];
// print: sum
for(int x = 10; x < 1000000000; x++){
if(b < x){
c = a*x + b;
break;
}
}
Here
int a = 2;
int b = 3;
char str[80];
char stringNum[20];
char *success;
success = malloc(20 * sizeof(*success));
sprintf(stringNum, "%d", a); // converts int a into a string
strcpy(str, stringNum); // initializes str
sprintf(stringNum, "%d", b);
strcat(str, stringNum);
printf("%ul", strtol(str, &success, 10)); // you'll get an int 23
free(success);
Just modify the values of the int variables to suit your needs and concatenate them to str.

implementation of trapezoidal numerical integration in C

I'm trying to implement numerical integration using the trapezoidal approximation using this formula :
My problem is I don't get how to implement this correctly. To test I wrote a file with 22050 double values all equal to 2 like :
....................
value =2.0;
for ( index = 0 ; index < 22050;index++){
fwrite(&value,sizeof(double),1,inp2);
}
to keep the question simple, say I want to the integral value of each 100 samples:
X Area integral value
0-100 should be 200
100-200 should be 200
..... ...........
22000-22050 should be 100
to do that I 've wrote a program that should do that but the result that get is 4387950 for 100 samples here is my code :
..............................
// opening the files
double* inputData= NULL;
unsigned int N = 100;
double h= 0.0;
unsigned int index= 0;
FILE* inputFile=NULL;
double value =0.0;
int i =0,j=0;
inputFile = fopen("sinusD","rb");
outputFile=fopen("Trapez","wb+");
if( inputFile==NULL || outputFile==NULL){
printf("Couldn't open the files \n");
return -1;
}
inputData = (double*) malloc(sizeof(double)*N);
h=22050/2;
while((i = fread(inputData,sizeof(double),N,inputFile))==N){
value += inputData[0] +inputData[N];
for(index=1;index<N;index++){
value+=(2*inputData[index]);
}
value *=h;
fprintf(outputFile,"%lf ",value);
value =0;
}
if(i!=0){
value = 0;
i=-i;
printf("i value %i\n", i);
fseek(inputFile,i*sizeof(double),SEEK_END);
fread(inputData,sizeof(double),i,inputFile);
for(index=0;index<-i;index++){
printf("index %d\n",index);
value += inputData[0] +inputData[i];
value+=(2*inputData[index]);
}
value *=h;
fprintf(outputFile,"%lf ",value);
value =0;
}
fclose(inputFile);
fclose(outputFile);
free(inputData);
return 0;}
any idea how to do that ?
UPDATE
while((i = fread(inputData,sizeof(double),N,inputFile))==N){
value = (inputData[0] + inputData[N])/2.0;
for(index=1;index<N;index++){
value+=inputData[index];
}
value *=h;
fprintf(outputFile,"%lf ",value);
printf(" value %lf\n",value);
value =0;
}
I get 199.000 as a result for each segment .
Why you didn't start with something simple. Let's say you have the following data {1,2,3,4,5,6,7,8,9,10} and assume h = 1. This is simple,
#include <stdio.h>
#define SIZE 10
int main()
{
double a[SIZE] = {1,2,3,4,5,6,7,8,9,10}, sum = 0.0, trapz;
int h = 1;
int i = 0;
for ( i; i < SIZE; ++i){
if ( i == 0 || i == SIZE-1 ) // for the first and last elements
sum += a[i]/2;
else
sum += a[i]; // the rest of data
}
trapz = sum*h; // the result
printf("Result: %f \n", trapz);
return 0;
}
This is the result
Result: 49.500000
Double check your work with Matlab:
Y = [1 2 3 4 5 6 7 8 9 10];
Q = trapz(Y)
Q =
49.5000
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
Edit: For your question in the comment:
This is the matlab code:
X = 0:pi/100:pi; % --> h = pi/100
Y = sin(X); % get values as many as the size of X
Q = trapz(X,Y);
Q =
1.9998
Now to fulfil same scenario in C, do the following
#include <stdio.h>
#include <math.h>
#define SIZE 101
#define PI 3.14159265358
int main()
{
double X[SIZE], Y[SIZE], incr = 0.0, h = PI/100.0, sum = 0.0, trapz;
int i = 0, k = 0, j = 0;
// Generate samples
for ( i; i < SIZE; ++i)
{
X[i] = incr;
incr += h;
}
// Generate the function Y = sin(X)
for ( k; k < SIZE; ++k)
{
Y[k] = sin(X[k]);
}
// Compute the integral of sin(X) using Trapezoidal numerical integration method
for ( j; j < SIZE; ++j){
if ( j == 0 || j == SIZE-1 ) // for the first and last elements
sum += Y[j]/2;
else
sum += Y[j]; // the rest of data
}
trapz = sum * h; // compute the integral
printf("Result: %f \n", trapz);
return 0;
}
The result is
Result: 1.999836
First, your equation is correct, so that's a good start. However, there are a number of variable declarations that you don't supply in your question, so we're left to guess.
First, let's start with the math. For the integral from 0 to 100 to equal 200 with each value being equal to 2.0 implies that h = 1 but your code seems to use a value of 22050/2 which is probably not really what you want.
The code within the loop should look like this:
double value = (inputData[0] + inputData[N])/2.0;
for(index = 1; index < N; ++index){
value += inputData[index];
}
value *= h;
This will give the integral from 0 to N. If you wish to calculate between two arbitrary values, you will have to modify the code appropriately:
int a = 100; // lower limit
int b = 200; // upper limit
double value = (inputData[a] + inputData[b])/2.0;
for(index = a+1; index < b; ++index){
value += inputData[index];
}
value *= h;
As a full example of use, here's a program to calculate the integral of sin(x) from x=pi/4 to x=pi/2:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define M_PI 3.14159265358979323846
int main()
{
int a = 45; // 45 degrees = pi/4 radians
int b = 90; // 90 degrees = pi/2 radians
double h = M_PI/180; // how far apart are samples?
double *inputData = malloc(360*sizeof(double));
if (inputData == NULL) {
printf("Error: ran out of memory!\n");
exit(1);
}
for (int i=0; i<360; ++i)
inputData[i] = sin(i*h);
double value = (inputData[a] + inputData[b])/2.0;
for (int index = a+1; index < b; ++index)
value += inputData[index];
value *= h;
printf("integral from %d to %d = %f\n", a, b, value);
double expected = 1.0/sqrt(2);
printf("(expected value = %f, error = %f)\n", expected, expected-value);
free(inputData);
}
Output from this program on my machine:
integral from 45 to 90 = 0.707089
(expected value = 0.707107, error = 0.000018)

Resources