How to extract a number/byte from an array in C? - c

Here i have written a code which produces next 8 numbers from sequence.
int next_exp_data(unsigned long long int expected_data)
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
unsigned long long int temp_data[10];
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
I want to know how can i extract each byte/number of the array and return each number/byte ??Please help me out.
EDIT:Here's my code.Basically i want to read a file and compare the contents to check if the data read matches with generated sequential data.Here the buffer contains same data as temp_data is producing(ie 10 numbers like 0x07060504030201 next 0f0e0d0c0b0a0908 etc).I want to comapre buffer's data and the function's data.Can anyone suggest me how can i do.I am stuck.Any changes are appreciated.
#include<stdio.h>
#include<stdlib.h>
#include<inttypes.h>
int main(void){
FILE *fp;
char *buffer,c;
size_t filesize,buffer_size;
int i;
unsigned long long int expected_data=1976943448883713;
fp=fopen("seqdata.c","r");
if(fp==NULL){
fputs("Error\n",stderr);
exit(1);
}
fseek(fp,0L,SEEK_END);
filesize=ftell(fp);
printf("Size of seqdata file is:%u \n",filesize);
fseek(fp,0L,SEEK_SET);
buffer=(char*)malloc(sizeof(char)*filesize);
if(buffer == NULL){
fputs("\nMemory error ",stderr);
}
buffer_size=fread(buffer,sizeof(char),filesize,fp);
for(i=0;i<buffer_size;i++){
printf("%c",*(buffer +i));
}
printf("No of elements read from file are:%u \n",buffer_size);
fseek(fp,0L,SEEK_SET);
int current_pos = 0;
while(current_pos < buffer_size){
if(*(buffer +current_pos) != expected_data)
{
fputs("Error\n",stderr);
exit(1);
}
else{
printf("data matching \n");
current_pos++;
expected_data=next_exp_data(expected_data);
}
}
fclose(fp);
free(buffer);
return 0;
}
int next_exp_data(unsigned long long int expected_data)
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
unsigned long long int temp_data[10];
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}

It's machine dependent, but this usually works one of two ways:
union {
unsigned char b [8];
long long i;
} v;
v .i = seq_gen_value;
for (int j = 0; j < 8; ++j)
printf ("%d, ", v .b [j]);
On a little endian machine (x86, vax, etc.) the bytes come out with the least significant first. On a big endian machine, they come out with the most significant first.
By the way, it would be more useful to encode the "magic numbers" so that they can be more easily understood what they mean. For example, instead of 1976943448883713, write it as 0x7060504030201.

I think that your function do something like
return 1976943448883713 + 8 * 2260630401189896
And I think your question is not clear enough, like what array you want to return each its number? If you want to return array temp_data, it very easy. You can do that by
int next_exp_data(unsigned long long int expected_data, unsigned long long int temp_data[])
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
Call this function with the second params is a array int with size 10.
And another thing, I don't think that this function need the 1st param, because it's not be used within the function, so you can remove that from functions params list
int next_exp_data( unsigned long long int temp_data[])
{
int i=0;
unsigned long long int expected_data;
unsigned long long int seq_gen_value=1976943448883713;
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return expected_data; //dont use (expected_data), it will make things slower.
}

Comparing numbers in C is done using ==, !=, <= , >= , <, or >.
I didn't read your code as it's horrible formatted and doesn't seem relevant to your question as posed in the title.

Related

How to store individual units of an int in an int array; C Language

I am a beginner starting in C and am doing some exercises on codewars. The exercise requires me to take a decimal int, convert it into binary and output the number of 1s in the binary number. Below my incomplete code. I store the binary in int b and I want to output it into an array so that I can run a loop to search for the 1s and output the sum.
Thanks in advance!
#include <stddef.h>
#include <stdio.h>
//size_t countBits(unsigned value);
int countBits(int d);
int main() {
int numD = 1234;
int numB = countBits(numD);
printf("The number %d converted to binary is %d \n", numD, numB);
}
int countBits(int d) {
if (d < 2) {
return d;
} else {
int b = countBits(d / 2) * 10 + d % 2; //convert decimal into binary
int c;
int bArray[c];
}
Your function is almost correct:
you should define the argument type as unsigned to avoid problems with negative numbers
you should just return b in the else branch. Trying to use base 10 as an intermediary representation is useless and would fail for numbers larger than 1023.
Here is a corrected version:
int countBits(unsigned d) {
if (d < 2) {
return d;
} else {
return countBits(d / 2) + d % 2;
}
}
There are many more efficient ways to compute the number of bits in a word.
Check Sean Eron Anderson's Bit Twiddling Hacks for classic and advanced solutions.
You can make an array char as one of the replies said, for example:
#include <stdio.h>
#include <string.h>
int main(){
int count=0;
int n,bit;
char binary[50];
printf("Enter a binary: \n");
scanf("%s",binary);
n=strlen(binary);
for(int i=0;i<n;i++){
bit=binary[i]-'0';
if (bit==1){
count=count+1;
}
}
printf("Number of 1's: %d\n",count);
return 0;
}
This should count the number of 1's of a given binary.
Try something like this!
edit: I know that binary[i]-'0' might be confusing, if you don't understand that..take a look at this:
There are definitely 'smarter'/more compact ways to do this, but here is one way that will allow you to count bits of a bit larger numbers
#include <stdio.h>
int count_bits(int x)
{
char c_bin[33];
int count=0;
int mask=1;
for( int i =0; i < 32; i++){
if (x & mask ){
count=i+1;
c_bin[31-i]='1';
}
else{
c_bin[31-i]='0';
}
mask=mask*2;
}
c_bin[32]='\0';
printf("%d has %d bits\n",x,count);
printf("Binary x:%s\n",c_bin);
return count;
}
int main()
{
int c=count_bits(4);
return 0;
}

Array of 20000000 elements limits [duplicate]

This question already has answers here:
Segmentation fault on large array sizes
(7 answers)
Closed 4 years ago.
For a university project, I have to sort a CSV file of 20 million records (wich are represented in 2^64 bit, for example, 10000000 or 7000000, so I used unsigned long long) using MergeSort. So, I developed this C file:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
// Path to the dataset
#define DATASET_PATH "/Volumes/HDD/Lorenzo/Unito/2 Anno/ASD/Progetto/Progetto 2017-2018/laboratorio-algoritmi-2017-18/Datasets/ex1/integers.csv"
#define ELEMENTS_TO_SCAN 1000000 // the numbers of elements to be scanned
void mergeSort(unsigned long long * arrayToSort, int leftIndex, int rightIndex);
void merge(unsigned long long * arrayToSort, int left, int center, int right);
void read();
void printArray();
// from "Introduction to Algorithms" of T. H. Cormen
void mergeSort(unsigned long long * arrayToSort, int leftIndex, int rightIndex){
if(leftIndex < rightIndex){
int center = (leftIndex + rightIndex) / 2;
mergeSort(arrayToSort, leftIndex, center);
mergeSort(arrayToSort, center + 1, rightIndex);
merge(arrayToSort, leftIndex, center, rightIndex);
}
}
// from "Introduction to Algorithms" of T. H. Cormen
void merge(unsigned long long * arrayToSort, int left, int center, int right){
int n1 = center - left + 1;
int n2 = right - center;
unsigned long long leftSubArray[n1+1];
unsigned long long rightSubArray[n2+1];
leftSubArray[n1] = ULLONG_MAX; // here Cormen use infinite
rightSubArray[n2] = ULLONG_MAX; // here Cormen use infinite
for(int i = 0; i < n1; i++)
leftSubArray[i] = arrayToSort[left + i];
for(int j = 0; j < n2; j++)
rightSubArray[j] = arrayToSort[center + j + 1];
int i = 0;
int j = 0;
int k = 0;
for(k = left; k <= right; k++){
if(leftSubArray[i] <= rightSubArray[j]){
arrayToSort[k] = leftSubArray[i];
i++;
} else {
arrayToSort[k] = rightSubArray[j];
j++;
}
}
}
// it reads all the dataset, and saves every line (wich contains a single element)
// in a position of an array to sort by MergeSort.
void read(char pathToDataset[], unsigned long long arrayToFill[]) {
FILE* dataset = fopen(pathToDataset, "r");
if(dataset == NULL ) {
printf("Error while opening the file.\n");
exit(0); // exit failure, it closes the program
}
int i = 0;
while (i < ELEMENTS_TO_SCAN && fscanf(dataset, "%llu", &arrayToFill[i])!=EOF) {
//printf("%llu\n", arrayToFill[i]); // ONLY FOR DEBUG, it wil print 20ML of lines!
i++;
}
printf("\nRead %d lines.\n", i);
fclose(dataset);
}
void printArray(unsigned long long * arrayToPrint, int arrayLength){
printf("[");
for(int i = 0; i < arrayLength; i++) {
if (i == arrayLength-1) {
printf("%llu]", arrayToPrint[i]);
}
else {
printf("%llu, ", arrayToPrint[i]);
}
}
}
int main() {
unsigned long long toSort [ELEMENTS_TO_SCAN] = {};
read(DATASET_PATH, toSort);
mergeSort(toSort,0,ELEMENTS_TO_SCAN-1);
printf("Merge finished\n");
return 0;
}
after some testing, if ELEMENTS_TO_SCAN is bigger than 500000 (= 1/4 of 20 million) i don't know why, but the output on the terminal is
Segmentation fault: 11
Someone can help me?
You’re doing a local variable declaration (eg on stack). If you’re dealing with larger arrays, consider making them global, or use dynamic arrays — in general dynamic would be better. Using globals makes it easier to get into bad habits.
Why are global variables bad, in a single threaded, non-os, embedded application
Segmentation fault 11 because of a 40 MB array in C
As people pointed out, this type of allocation can't be done on Stack. I would try dynamically allocating it, for that you just need to change the code like so:
int main() {
unsigned long long *toSort;
toSort = (unsigned long long) malloc(ELEMENTS_TO_SCAN*sizeof(unsigned long long));
read(DATASET_PATH, toSort);
mergeSort(toSort,0,ELEMENTS_TO_SCAN-1);
printf("Merge finished\n");
free(toSort);
return 0;
}
As you pointed the merge is the one causing problems. Just to note, if you use things like:
int array[n];
You will run into problems eventually, that's a given. If you don't know how much memory you will use at compile time, either use a data structure that supports the resizing like linked lists or dynamically allocate it .

SPOJ AGS runtime error

I was practising dynamic programming on SPOJ. I am stuck on this problem named AGS. Below is my code. It is giving runtime error on SPOJ but is running perfectly fine on my computer. Please help
#include<stdio.h>
long long mypow(long long base,long long exp,long long mod,long long log[])
{
if(log[exp]!=0)
return log[exp];
if(exp==0)
return 1;
if(exp==1)
return base%mod;
long long ans = ((base%mod) * mypow(base,exp-1,mod,log))%mod;
log[exp]=ans;
return ans;
}
long long gpsum(long long r,long long k,long long mod,long long log[])
{
if(k==0)
return 1;
if(k==1)
return 1+r;
long long ans=(mypow(r,k,mod,log)+gpsum(r,k-1,mod,log))%mod;
return ans;
}
int main()
{
long long i,t,k,a,d,r,n,mod,p,q,ans;
scanf("%lld",&t);
while(t--)
{
scanf("%lld %lld %lld",&a,&d,&r);
scanf("%lld %lld",&n,&mod);
long long log[n/2];
for(i=0;i<n/2;i++)
log[i]=0;
if(n==1)
{
ans=a;
}
else if(n%2==0)
{
k=(n-2)/2;
p=mypow(r,k,mod,log);
q=gpsum(r,k,mod,log);
ans=(((p%mod)*(a%mod))%mod+((q%mod)*(d%mod))%mod)%mod;
}
else
{
k=(n-3)/2;
p=r*mypow(r,k,mod,log);
q=r*gpsum(r,k,mod,log);
ans=(((p%mod)*(a%mod))%mod+((q%mod)*(d%mod))%mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
It looks like the line long long log[n/2]; causing the error. For n = 12345678 (from the sample input in the comments) it will try to allocate around 6M of long long which is about 50Mb on the stack. Which is, I am guessing, too big for the online multi user compilers. The following code will prove this claim:
#include<stdio.h>
#define MAX 7000000
int main()
{
volatile long long v[MAX];
long i;
for ( i=0; i<MAX; i++ )
v[i]=i+1;
printf("Hello");
return 0;
}
The value of MAX as stated will give the error on ideone. Reducing the value, say to 700000 will remove the error (don't mind the volatile and the loop exercises, they are there to trick on optimizer).
A possible solution would be allocating this memory statically, as a global variable - outside the main function, such that it will go to the .data section, and not to the stack. This solution:
#include<stdio.h>
#define MAX 7000000
volatile long long v[MAX];
int main()
{
long i;
for ( i=0; i<MAX; i++ )
v[i]=i+1;
printf("Hello");
return 0;
}
works just fine even with larger numbers.

I have seg fault in my counting sort

Here is my code, for some reason I have to use unsigned long. The gdb tells me that I have
seg fault. Can one can help me? I could not find it by myself. The most interesting thing is that if I change the type to int from unsigned long, there is no seg fault.
Code is here:
#include <stdio.h>
int counting_Sort (unsigned long ary[], unsigned long array_size,unsigned long max){
unsigned long counting[max+1];
unsigned long j;
for(j=0;j<max+1;j++){
counting[j]=0;//initize to zero
}
unsigned long i;
for(i=0;i<array_size;i++){
counting[ary[i]]++;
}
unsigned long q;
for(q=1;q<max+1;q++){
counting[q]=counting[q-1]+counting[q];
}
for(q=0;q<max+1;q++){
counting[q]=counting[q]-1;
}
unsigned long outputAry[array_size];
unsigned long d;
for(d=(array_size-1); d>=0;d--){
outputAry[counting[ary[d]]]=ary[d];// SEG FAULT IS HERE
counting[ary[d]]--;//AND HERE
}
unsigned long m;
//for(m=0; m<array_size;m++){
// printf("%lu\n",outputAry[m]);
// }
return 0;
}
int main(){
unsigned long array[7]={2,6,4,0,1,7,9};
printf("before sorting the order is: \n");
unsigned long i;
for(i=0;i<7;i++){
printf("%lu\n",array[i]);
}
printf("after sorting, the new order is: \n");
counting_Sort(array,7,9);
getchar();
return 0;
}
You've found the place, just not the reason.
unsigned long d;
for(d=(array_size-1); d>=0;d--){
d is an unsigned integer, which means d>=0 is always true. The loop never ends, and that's the reason of segmentation fault.
One way is to change d to a singed type:
int d;
But if that's not what you want, change the for loop to:
for (d = 0; d <= array_size - 1; d++){

Understanding unsigned 0 in C

I am trying to understand number representation in C.
I am working on a code segment which looks like the one below.
#include <stdio.h>
#include <string.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, int len)
{
int i;
for (i = 0; i < len; i++)
printf(" %.2x", start[i]);
printf("\n");
}
void show_int(int x) {
show_bytes((byte_pointer) &x, sizeof(int));
}
void show_unsigned(short x) {
show_bytes((byte_pointer) &x, sizeof(unsigned));
}
int main(int argc,char*argv[])
{
int length=0;
unsigned g=(unsigned)length;// i aslo tried with unsigned g=0 and the bytes are the same
show_unsigned(g);
show_int(length);
printf("%d",g);//this prints 0
return 0;
}
Here, show_unsigned() and show_int() prints the byte representations of the variables specified as arguments.For int length the byte representation is all zeroes as expected, but for unsigned g, the byte representation is 00 00 04 08.But when I print g with a %d, I get 0(so i suppose the numeric value is interpreted as 0 )
Please could somebody explain how this is happening.
In:
void show_unsigned(short x) {
show_bytes((byte_pointer) &x, sizeof(unsigned));
}
You declared the argument short x which is smaller than int x so you ignored some of the 00 and your print function is displaying adjacent garbage.
You're reading sizeof(unsigned) bytes in a short. short isn't guaranteed to be the same size as unsigned, hence, when reading the bytes next to your short, garbage data is read.
To fix this, either pass your argument as an unsigned, or when using sizeof, use sizeof(short).
what you are doing doesn't make any sense, particularly with the type conversions that you have occurring. Someone else already pointed out my point about the conversion to short
Rather than writing an absurd number of functions try doing this
void show_bytes( void *start, unsigned int len ) {
unsigned char* ptr = (unsigned char *) start;
unsigned int i = 0;
for ( i = 0; i < len; ++i, ++ptr ) {
printf( " %.2x", ptr[0] );
}
}
Instead of calling as you had been just call it like:
show_bytes( (void *)&x, sizeof(x));
And if thats too much typing make a macro out of that. now it works for any type you come up with.

Resources