I am trying to read/write hexadecimals into a 2D integer array for my program, but there are issues with some hexadecimals.
When I input 272cf50 it accurately turns into 41078608 in the array and I have no problems.
But when I input ffff0000000 it turns into -268435456 instead of its decimal equivalent: 17591917608960.
Because of this when I try to check if ffff0000000 already exists in the array it says it doesn't even though I wrote it into the array. I am confused about why this is happening and how I can fix it.
This is the code:
bool inCache(unsigned long addy, unsigned long blockid, unsigned long setidx, int size, int** cache, int lps){
//find set index
//find easier way
int i=0;
while(cache[i][0]!=setidx){
i++;
}
//check if set contains blockid
for(int j=0; j<lps; j++){
if(cache[i+j][2]==1 && cache[i+j][1]==blockid){
return true;
}
}
//not in cache
return false;
}
void read(unsigned long addy, unsigned long blockid, unsigned long setidx, int size, int** cache, int lps){
unsigned long x = blockid;
bool e = inCache(addy,blockid,setidx,size,cache,lps);
if(e==true){
ch++;
}else{
cm++;
mr++;
//set x in cache
newWrite(addy,x,setidx,size,cache,lps);
}
}
void newWrite(unsigned long addy, unsigned long blockid, unsigned long setidx, int size, int** cache, int lps){
//check if already loaded in cache
bool e = inCache(addy,blockid,setidx,size,cache,lps);
if(e!=true){
//load the block into chosen cache line
//find the setidx
int i=0;
while(cache[i][0]!=setidx){
i++;
}
//go thru set and put into first available cacheline
for(int j=0; j<lps; j++){
if(cache[i+j][2]==0){
cache[i+j][2]=1;
cache[i+j][1]=blockid;
break;
}
}
//if all cachelines are full, put into least recent cacheline
cache[i][1]=blockid;
}
}
This is the specific example:
0x1: R 0xffff0000000
0x2: R 0xffff0000000
In my particular example, for the first line the read function gets called and since the value is not in the array(cache) it calls the newWrite funciton to add it to the array. When it is added to the cache is when it converts to -268435456. Then, for the second line when the read function checks if the value is in the array it returns false instead of true.
This is a prime example of an integer overflow. Precisely what happened, was that the inputted number was interpreted as two’s complement. The number was so long that the sign bit got flipped. Indeed,
0xFFFF0000000 - 2⁴⁴ = -268435456
which is where that mysterious number came from.
Surely the best way to manage this situation is to keep care that the variables used can hold numbers that big, or to reject too large values.
EDIT with more information
The code shows that the array’s signature is int **. This should be unsigned too in order to make the comparison to work. The following code demonstrates the problem:
#include <stdio.h>
int main(void)
{
int a = 0xffff0000000;
unsigned long b = 0xffff0000000;
printf("%d\n",a==b);
/* the number zero (meaning "false") is printed */
}
Related
I am writing a code to find the factor of the user given number. And then I want to store all the factors in an array. I created two functions, factors and insert_element. factors will find the factor and insert_element will store the factor in array as loop continues. When i call insert_element function form factors it shows me an error like warning: passing argument 1 of ‘insert_element’ from incompatible pointer type [-Wincompatible-pointer-types]. I have no idea what this means and how it occurred as I am new at C language. I would like to know how a bit about how compiler works with array along with how this error occurred
I am extremely SORRY if the question title and the question body seems to be misleading..
Here's my code below:
// PROGRAME TO FIND FACTORS OF GIVEN NUMBER"
#include <stdio.h>
void insert_element(int *factor_array[], int *base_divisor, int *index_of_array_elements)
//I heve used * because i want to ruturn more then one thing
{
*factor_array[*index_of_array_elements] = *base_divisor;
*index_of_array_elements++;
}
void factors(int number)
// I dont know if I want to return something or not so i kept it of type void
{
int base_divisor = 2, factor_array[50], index_of_array_elements = 0;
// base_divisor starts dividing given number from 2
while (number != 1)
{
if (number % base_divisor==0) //If remainder is zero then only devide number by base_divisor
{
number = number / base_divisor;
}
else //If remainder is not zero then base_divisor will be increase by 1.
{
base_divisor++;
}
// calling the function to insert element in array
insert_element(&factor_array[50], &base_divisor, &index_of_array_elements);
}
//i dont know why i did this but error is not caused by this.
printf("%ls", factor_array);
}
int main()
{
int number;
printf("\nPROGRAME TO FIND FACTORS OF GIVEN NUMBER\n\n");
printf("Enter the number to find factor: ");
scanf("%d", &number);
factors(number);
}
As written, the code in your post is outputting values that are not always factors. Only during the final iteration of the loop is the value for factor_array (if stored correctly) a quotient and a factor, which of course should also mean it is prime.
The following example, for simplification removes one function, and modifies the prototype of the remaining function to take a struct array argument. The struct itself contains values for quotient, factor, base. The code is also commented to explain some of the modification. In particular I hope this will help you to understand how to pass an array as a function argument, and how to use a loop to output the values in an array.
typedef struct {
long long factor;
long long quotient;
long long base;
}elements_s;
elements_s factor_array[50] = {{0}};
//REMOVED as all the work done here is moved to it's calling function
// void insert_element(size_t arr_size int *factor_array[], int *base_divisor, int *index_of_array_elements)
////I heve used * because i want to ruturn more then one thing
//{
//
// *factor_array[*index_of_array_elements] = *base_divisor;
// *index_of_array_elements++;
//
//
//}
void factors(long long number, size_t size, elements_s arr[size])//changed to pass container for results.
// I dont know if I want to return something or not so i kept it of type void
{
long long base_divisor = 2, /**factor_array[50],*/ index_of_array_elements = 0;//factor_array replaced by struct array
arr[index_of_array_elements].factor = 1;//fill array here, no need to send via function
arr[index_of_array_elements].quotient = number;
arr[index_of_array_elements].base = base_divisor;
int i=0;
// base_divisor starts dividing given number from 2
while (number != 1 && base_divisor < LLONG_MAX )
{
if (number % base_divisor==0) //If remainder is zero then only devide number by base_divisor
{
index_of_array_elements++;//index array index
number = number / base_divisor;
arr[index_of_array_elements].factor = base_divisor;//fill array here, no need to send via function
arr[index_of_array_elements].quotient = number;//fill array here, no need to send via function
arr[index_of_array_elements].base = base_divisor;//fill array here, no need to send via function
}
else //If remainder is not zero then base_divisor will be increase by 1.
{
base_divisor++;
}
//REMOVED for simplification of example (Not needed)
// calling the function to insert element in array
//insert_element(&factor_array[50], &base_divisor, &index_of_array_elements);
//insert_element(&factor_array, &base_divisor, &index_of_array_elements);
}
//i dont know why i did this but error is not caused by this.
for(i = 0;i < index_of_array_elements-1; i++)//putting into loop so all populated element of array are output
{
printf("quotient:%lld\nfactor:%lld\n", factor_array[i].quotient,factor_array[i].factor);//using %d for int
}
printf("base divisor:%lld\nfactor and quotient:%lld\nfactor:%lld\n", factor_array[i].base, factor_array[i].quotient,factor_array[i].factor);//using %d for int
}
int main(void)//this is a minumum signature for main. Anything less is not portable.
{
long long number = 0; //allows larger values up to 9223372036854775807 (LLONG_MAX)
//int factor_array[50] = {0};
size_t size = sizeof factor_array/sizeof *factor_array;
printf("\nPROGRAME TO FIND [prime] FACTORS OF GIVEN NUMBER\n\n");
printf("Enter the number to find factor...\n");
scanf("%lld", &number);//format specifier changed to accomodate larger type
factors(number, size, factor_array);//factor_array contains all the results here,
// so prinf could be used here if index were
// also passed as argument
return 0;//int main(void) requires this statement
}
Example run for value: 1234567890: (multiply all factors to test for input)
given a unsigned 64 bit integer.
which has multiple bits set in it.
want to process the bitmap and identify the position and return the string according to the position where bit is it.
example: unsigned integer is 12. means 1100 which implies third bit and fourth bit are set. this should print THREE FOUR
function takes unsigned int and returns string.
I looked some pieces of code and i don't see this as a dup of some other question.
char* unsigned_int_to_string(unsigned long int n)
{
unsigned int count = 0;
while(n)
{
int i, iter;
count += n & 1;
n >>= 1;
}
/*** Need help to fill this block ***/
/** should return string THREE FOUR***/
}
#include <stdio.h>
int main()
{
unsigned long int i = 12;
printf("%s", unsigned_int_to_sring(i));
return 0;
}
You could brute force it by having a lookup table which has a word representation for each bit you're interested in.
char* bit_to_word[10] = { "ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE","TEN" }; // and so forth...
Then in your function check every bit and if it is set, concatenate the corresponding word from your bit_to_word array. You can safely do this by using the strcat_s function.
strcat_s(number_string, BUF_SIZE, bit_to_word[i]);
One gotcha. After the first word you will want to add a space as well so you might want to keep track of that.
This code checks the first 10 bits of the number and prints out THREE FOUR for the test case. Be aware though that it doesn't do any memory cleanup.
#include <stdio.h>
#include <string.h>
#define BUF_SIZE 2048
char* bit_to_word[10] = { "ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE","TEN" };
char* unsigned_int_to_string(unsigned long int n)
{
char* number_string = (char*)malloc(BUF_SIZE);
memset(number_string, 0, BUF_SIZE);
int first_word = 1;
unsigned long int tester = 1;
int err;
for (unsigned long int i = 0; i < 10; i++)
{
if (tester & n)
{
if (!first_word)
{
strcat_s(number_string, BUF_SIZE, " ");
}
err = strcat_s(number_string, BUF_SIZE, bit_to_word[i]);
if (err)
{
printf("Something went wrong...\n");
}
first_word = 0;
}
tester <<= 1;
}
return number_string;
}
int main(int argc, char** argv)
{
char* res = unsigned_int_to_string(0b1100);
printf("%s\n", res);
}
Without writing the actual code, here is the description of a simple algorithm based on a 64 element lookup table of strings. 0 = ZERO, 1 = ONE, 2 = TWO ... 63 = SIXTY THREE. This table will be a 64 element array of strings. For C, you could make a static 2D array using char[256] to hold your strings (or optimize by using the value of the largest string + 1), or you could make a dynamic using malloc in a For Loop)
You then define your output string.
You then write a For Loop, iterating through all the bits using a bit mask (using left shift) if the Bit is set you can concatenate your output string (using strcat) with a space and the contents of your lookup table for that bit position.
Here is a brief code snippet on how you will do the concatenation: (Make sure you output string has enough memory in the outputstring variable to hold the largest string. If you want to be more sophisticated and optimize mem usage, you could use malloc and realloc, but you have to deal with freeing the memory when it is no longer needed.
#include <stdio.h>
#include <string.h>
int main ()
{
char str[80];
strcpy (str,"these ");
strcat (str,"strings ");
strcat (str,"are ");
strcat (str,"concatenated.");
puts (str);
return 0;
}
In your case, bit 3 will be encountered as the first set bit and the output string will then contain "THREE", then on the next iteration bit 4 will be detected as set and the output will be appended as "THREE FOUR".
Note: Because this appears to be an academic problem I would like to point out that there exists here the classical case of complexity vs space trade off. My description above was minimum complexity at the expense of space. Meaning, you will have 64 strings with redundancy in many of these strings. For example: TWENTY TWO, THIRTY TWO, FOURTY TWO, FIFTY TWO, and SIXTY TWO, all contain the string "TWO". Space could be optimized by using half the strings: ZERO, ONE, through NINETEEN, then TWENTY, THIRTY, FORTY, FIFTY, SIXTY. However, your indexing logic will be more complicated for bits greater than TWENTY. for bit 21 you will need to concatenate TWENTY and ONE.
I cannot understand how this code is causing a segfault when I run it, can anyone help me understand what is going on??
#include <stdio.h>
unsigned long long factorial(unsigned long long x, unsigned long long amt)
{
if (x == 1ULL) return amt;
else return factorial(x-1ULL, amt*x);
}
int main(int argc, char *argv[])
{
for (unsigned long long i = 0; i < 10ULL ;i++) {
printf("%llu\n", factorial(i, 1ULL));
}
}
First, the segfaults are not necessarily caused be invalid pointer dereference. In this case, it is actually caused by infinite recursion and eventual running out of stack space. Why? The essential requirement of a recursion function is it has to finish and terminate the recursion at some state, if you look carefully your code, in function factorial, if x is 0, then the recursion will become endless and eventually crash your program. You can fix this by change the terminate condition to:
if (x <= 1ULL) return amt;
In the orginal code :
if (x == 1ULL) return amt;
is meant to be the exit condition for this recursive function factorial. However when a value of zero is passed to the function and given that the type of x is unsigned long long, first recursive call to the function factorial with the parameter x-1ULL would set the value of x to very large value (18446744073709551615 is what I got here). Successive recursive calls to factorial will gradually deplete the stack space allocated for the program to the point where you get a segmentation fault.
You should have been doing this:
#include <stdio.h>
unsigned long long factorial(unsigned long long x, unsigned long long amt)
{
if (x == 0ULL) // Changed the exit condition, see Reference [1]
return amt; // Bear in mind that the initial value for amt you passed is 1
amt*=x; // See Reference [2]
return factorial(x-1ULL, amt);
}
int main(int argc, char *argv[]) {
for (unsigned long long i = 0; i < 10ULL ;i++) {
printf("%llu\n", factorial(i, 1ULL));
}
}
References
The idea of the factorial (in simple terms) is used to compute the number of permutations (combinations) of arranging a set of n numbers. It can be said that an empty set can only be ordered one way, so 0! = 1. Check this.
I feel this is more readable than factorial(x-1ULL, amt*x)
Note
The ULL suffixes are redundant here and may be removed altogether.
i'm writing a code for a number on a led segement to decrease by 1 every five seconds
my actual code at the moment is this
FiveSecDelay+=1;
if (FiveSecDelay ==100)
{
count2--; //decrement count2
for (uint32_t x = 0; x < 4; x++) //split count to to individual digits
{
new_value[x] = count2 % 10;
count2 = count2 / 10;
}
for (uint32_t i = 0; i < 4; i++)
{
Segment_Write(Digit[i],new_value[i]); assign value to segments
}
FiveSecDelay =0;
}
im using a schedular to call a function every milisecond, in theory this supposed to work as i used the same technique to assign a value to the segments,
what happens is that i have a starting value of 8, and it supposed to got 7,6,5,4 and so on till 0, but for some reason it goes from 8 to 42 and stays there
I had tried to fix it but have come up short.
Any help would be great
Thank you
Quick and dirty way:
while(true)
{
check();
sleep(5);
}
int values[1];
int check(void)
{
if (values[0] > 0)
values[0]--;
}
If you have access to the system time, you can store the initial time the call was made, and then every time you query its value, check against the system time to determine the correct adjusted value, and a little snippet to set the value, like such:
// initialize
int check = 142;
unsigned long long time = getMillis();
int get_value(void)
{
unsigned long long time_factor = ((getMillis() - time) / (unsigned long long) 5);
if (time_factor > (unsigned long long) check)
return 0;
else
return check - time_factor;
}
void set_value(int v)
{
check = v;
time = getMillis();
}
Note that I don't know off the top of my head how to get the system time in c (though I bet you'd need #include <time.h>) so I made up a function called getMillis() which returns the system time as an unsigned long long (should be a 64 bit unsigned integer). The implementation is up to the reader.
It's also worth mentioning that you will experience a wraparound error after about 600 million years.
void check() {
static int array[] = {142}; // why are you using an array here?
(*array)--;
}
int main() {
while(true)
{
check();
usleep(5000); // approximate
}
return 0;
}
Have check take a parameter which is the number. Then have a counter in the main loop of your program that starts at some value, and is decremented every time check is called.
I'm assuming that you are doing something more complex than what your current check function does because obviously it doesn't do anything in the provided form. If you provide more information, we would be able to give you a more thorough and applicable solution.
I'm working on Project Euler #14 in C and have figured out the basic algorithm; however, it runs insufferably slow for large numbers, e.g. 2,000,000 as wanted; I presume because it has to generate the sequence over and over again, even though there should be a way to store known sequences (e.g., once we get to a 16, we know from previous experience that the next numbers are 8, 4, 2, then 1).
I'm not exactly sure how to do this with C's fixed-length array, but there must be a good way (that's amazingly efficient, I'm sure). Thanks in advance.
Here's what I currently have, if it helps.
#include <stdio.h>
#define UPTO 2000000
int collatzlen(int n);
int main(){
int i, l=-1, li=-1, c=0;
for(i=1; i<=UPTO; i++){
if( (c=collatzlen(i)) > l) l=c, li=i;
}
printf("Greatest length:\t\t%7d\nGreatest starting point:\t%7d\n", l, li);
return 1;
}
/* n != 0 */
int collatzlen(int n){
int len = 0;
while(n>1) n = (n%2==0 ? n/2 : 3*n+1), len+=1;
return len;
}
Your original program needs 3.5 seconds on my machine. Is it insufferably slow for you?
My dirty and ugly version needs 0.3 seconds. It uses a global array to store the values already calculated. And use them in future calculations.
int collatzlen2(unsigned long n);
static unsigned long array[2000000 + 1];//to store those already calculated
int main()
{
int i, l=-1, li=-1, c=0;
int x;
for(x = 0; x < 2000000 + 1; x++) {
array[x] = -1;//use -1 to denote not-calculated yet
}
for(i=1; i<=UPTO; i++){
if( (c=collatzlen2(i)) > l) l=c, li=i;
}
printf("Greatest length:\t\t%7d\nGreatest starting point:\t%7d\n", l, li);
return 1;
}
int collatzlen2(unsigned long n){
unsigned long len = 0;
unsigned long m = n;
while(n > 1){
if(n > 2000000 || array[n] == -1){ // outside range or not-calculated yet
n = (n%2 == 0 ? n/2 : 3*n+1);
len+=1;
}
else{ // if already calculated, use the value
len += array[n];
n = 1; // to get out of the while-loop
}
}
array[m] = len;
return len;
}
Given that this is essentially a throw-away program (i.e. once you've run it and got the answer, you're not going to be supporting it for years :), I would suggest having a global variable to hold the lengths of sequences already calculated:
int lengthfrom[UPTO] = {};
If your maximum size is a few million, then we're talking megabytes of memory, which should easily fit in RAM at once.
The above will initialise the array to zeros at startup. In your program - for each iteration, check whether the array contains zero. If it does - you'll have to keep going with the computation. If not - then you know that carrying on would go on for that many more iterations, so just add that to the number you've done so far and you're done. And then store the new result in the array, of course.
Don't be tempted to use a local variable for an array of this size: that will try to allocate it on the stack, which won't be big enough and will likely crash.
Also - remember that with this sequence the values go up as well as down, so you'll need to cope with that in your program (probably by having the array longer than UPTO values, and using an assert() to guard against indices greater than the size of the array).
If I recall correctly, your problem isn't a slow algorithm: the algorithm you have now is fast enough for what PE asks you to do. The problem is overflow: you sometimes end up multiplying your number by 3 so many times that it will eventually exceed the maximum value that can be stored in a signed int. Use unsigned ints, and if that still doesn't work (but I'm pretty sure it does), use 64 bit ints (long long).
This should run very fast, but if you want to do it even faster, the other answers already addressed that.