Division alg C to get floating point number - c

Hi I got this division alg to display the integer and floating point values.
How can I get MAX_REM? it is supposed to be the size of the buffer where our characters are going to be stored, so the size has to be the # of digits, but I don't know how to get that. thanks!
void divisionAlg(unsigned int value)
{
int MAX_BASE=10;
const char *charTable = {"0123456789ABCDEF"}; // lookup table for converting remainders
char rembuf[MAX_REM + 1]; // holds remainder(s) and provision null at the end
int index; //
int i; // loop variable
unsigned int rem; // remainder
unsigned int base; // we'll be using base 10
ssize_t numWritten; // holds number of bytes written from write() system call
base = 10;
// validate base
if (base < 2 || base > MAX_BASE)
err_sys("oops, the base is wrong");
// For some reason, every time this method is called after the initial call, rembuf
// is magically filled with a bunch of garbage; this just sets everything to null.
// NOTE: memset() wasn't working either, so I have to use a stupid for-loop
for (i=0; i<MAX_REM; i++)
rembuf[i] = '\0';
rembuf[MAX_REM] = 0; // set last element to zero
index = MAX_REM; // start at the end of rembuf when adding in the remainders
do
{
// calculate remainder and divide valueBuff by the base
rem = value % base;
value /= base;
// convert remainder into ASCII value via lookup table and store in buffer
index--;
rembuf[index] = charTable[rem];
} while (value != 0);
// display value
if ((numWritten = write(STDOUT_FILENO, rembuf, MAX_REM + 1)) == -1)
err_sys("something went wrong with the write");
} // end of divisionAlg()

The calculation for figuring out how many digits there are a number takes is:
digits = floor(log(number)/log(base))+1;
However, in this case, I'd probably just assume the worse case, since it's no more than 32, and calculating it will be "expensive". So just #define MAX_REM 32, and then keep track of how many digits you actually put into rembuf (you already have index for that, so it's no extra cost really). You'll obviously need to calculate the amount of bytes to write out as well, but shouldn't require any special math.

Related

Sorting a finite number of elements where each element takes 1 bit of memory in c

I'm trying to create a type set, that holds like so
typedef struct set
{
char *blocks;
char *numbers;
char blockNum;
};
then in order to create it I do
void createSet(set *newSet)
{
newSet->blockNum = 1;
newSet->blocks = calloc(newSet->blockNum, BYTE_SIZE);
}
I can initially get numbers from [0,127], with no duplicates
so in order to do that, I want to change the nth bit into 1, and then when I want to read the set, I look at the memory that set.blocks take, and check the position of each bit inside it, if a bit is equal to 1, then the number that is equal to the position of that bit is in the set.
here's the code for adding an item
void addItem(set *set, unsigned int item)
{
int blocksToAdd = 0;
int i = 0;
int r = (item / BYTE_SIZE);
int rem=item % BYTE_SIZE;
if (r > set->blockNum)
{
if(r!=0) {
blocksToAdd = r - (set->blockNum);
}
set->blocks = realloc(set->blocks, (set->blockNum + blocksToAdd)*BYTE_SIZE);
}
*(set->blocks+r) = (1 << rem);
}
also, I increase the memory of blocks, by adding the amount of bytes needed to get the nth amount of bits,
so far it kinda works, but when the selected number to add is 7, I get that *blocks: -128 when it supposed to be 128, I guess it happen cause the then *blocks = 1000 0000.
So, I tried working around it but I couldn't get it to work, and I'm pretty sure I'm doing something wrong.
the goal was to store numbers from [0,127] with no duplicates, in a way that each element(number) takes 1 bit of memory.
int num =*(set->blocks+r);
if(num<0) {
set->blocks = (char *)realloc(set->blocks, (set->blockNum + 1)*BYTE_SIZE);
num*=-1;
*(set->blocks+r) = num;
}
Tried doing this to get around it, but it wouldn't work
edit
I managed to fix the issue, by changing blocks from char* to unsigned char*, also allocated 16 bytes from the start since calling relloc to increase the size every time isn't efficient, so I would instead check if I can decrease the memory allocated for set after adding all the items

How compiler works with arrays?

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)

Access and store value by index in a pointer

I've got an assignment where I have to sum whole numbers up to 100 digits.
They gave me this struct to represent big numbers (I think there are better ways to represent this, but I'm not allowed to modify it):
typedef struct {
char* string;
int lengthError;
} BigNumber;
Where string is the number itself and lengthError is the length of the number or an error that is a previously defined enum.
I've also have the implementation of the sum function
BigNumber *sum(BigNumber* num1, BigNumber* num2) {
BigNumber* result = malloc(sizeof(BigNumber));
int limit = getLength(num1->lengthError, num2->lengthError);
result->string = malloc(limit);
int digitResult;
int index = limit -1;
int carry = 0;
while(index != -1) {
int d1 = ((int)num1->string[index]) - ((int)'0');
int d2 = ((int)num2->string[index]) - ((int)'0');
digitResult = d1 + d2 + carry;
if (digitResult > 9) {
digitResult = digitResult - 10;
carry = 1;
} else {
carry = 0;
}
itoa(digitResult, &result->string[index], 10); //I think this is the problem
index--;
}
result->string[limit] = '\0';
printf("result: %s\n", result->string);
return result;
}
I haven't finished writing that function, I know there are a lot of flaws in it, but the problem is that I can't get to sum 12 + 12. The result I get is 2.
I thought approaching this problem by picking the lasts character of both numbers, transform them into an int and sum them having in mind the carry digit. After I got the result in digitResult I try to convert it to a char and store it in the corresponding position of the result->string pointer
Once it has finished the operation, I add an \0 at the last position of the result->string.
So the question is, how do I make this operation to work as desired? Debugging the code, I noticed that the first time it stores the first result in result->string, following the example above this would be a number 4, it stores trash in that position instead. In the second addition, I store a number 2 correctly and that's the final result I get in when I print the result.
Your use of the itoa function is a problem (though, as you have also suggested, maybe not the only one).
The itoa function converts its first argument into a null-terminated string - so, as well as writing the character representation of digitResult at the indicated place in the string, it also adds a '\0' character after it. Thus, your string will always be terminated immediately after the last digit you write, and 12 + 12, giving 24 will appear to be just the first character: 2.
What you can do instead is to convert the digit yourself (reversing the operation you used to get the d1 and d2 values), then just directly set the string element to the converted digit.
So, instead of:
itoa(digitResult, &result->string[index], 10);
use:
result->string[index] = (char)(digitResult + '0');

Writing an array of integers into a file using C [duplicate]

This question already has answers here:
How to write an array to file in C
(3 answers)
Closed 3 years ago.
I would like to write an array of integers into a file using C. However, I get some gibberish in the file.
The code is about a function that converts a decimal number into binary then stores it into a file.
int * decToBinary(int n) //function to transform the decimal numbers to binary
{
static int binaryNum[16]; // array to store binary number
int i = 0; // counter for binary array
while (n > 0) {
binaryNum[i] = n % 2; // storing remainder in binary array
n = n / 2;
i++;
}
return binaryNum;
}
int main()
{
FILE *infile;
int i;
int *p;
int decimal= 2000;
int written = 0;
infile = fopen("myfile.txt","w");
p = decToBinary(decimal);
written = fwrite(p,sizeof(int),sizeof(p),infile) ;
if (written == 0) {
printf("Error during writing to file !");
}
fclose(infile);
return 0;
}
This is what I get in my file:
This is what I get when I write a text as a test, it does not have any problem with the text, but it has with the array.
char str[] = "test text --------- \n";
infile = fopen("myfile.txt","wb");
p=decToBinary(decimal);
fwrite(str , 1 , sizeof(str) , infile);
written = fwrite(p,sizeof(int),sizeof(p),infile) ;
And this is what I get when I make this change:
written = fwrite(&p,sizeof(int),sizeof(p),infile) ;
First, be aware that there are two interpretations for 'binary':
int n = 1012;
fwrite(&n, sizeof(n), 1, file);
This writes out the data just as is; as it is represented in form of bits, output is considered "binary" (a binary file).
Your question and the code you provided, though, rather imply that you actually want to have a file containing the numbers in binary text format, i. e. 7 being represented by string "111".
Then first, be aware that 0 and 1 do not represent the characters '0' and '1' in most, if not all, encodings. Assuming ASCII or compatible, '0' is represented by value 48, '1' by value 49. As C standard requires digits [0..9] being consecutive characters (this does not apply for any other characters!), you can safely do:
binaryNum[i] = '0' + n % 2;
Be aware that, as you want strings, you chose the bad data type, you need a character array:
static char binaryNum[X];
X??? We need to talk about required size!
If we create strings, we need to null-terminate them. So we need place for the terminating 0-character (really value 0, not 48 for character '0'), so we need at least one character more.
Currently, due to the comparison n > 0, you consider negative values as equal to 0. Do you really intend this? If so, you might consider unsigned int as data type, otherwise, leave some comment, then I'll cover handling negative values later on.
With restriction to positive values, 16 + 1 as size is fine, assuming int has 32 bit on your system! However, C standard allows int to be smaller or larger as well. If you want to be portable, use CHAR_BIT * sizeof(int) / 2 (CHAR_BIT is defined in <limits.h>; drop division by 2 if you switch to unsigned int).
There is one special case not covered: integer value 0 won't enter the loop at all, thus you'd end up with an empty string, so catch this case separately:
if(n == 0)
{
binaryNum[i++] = '0';
}
else
{
while (n > 0) { /.../ }
}
// now the important part:
// terminate the string!
binaryNum[i] = 0;
Now you can simply do (assuming you changed p to char*):
written = fprintf(file, "%s\n", p);
// ^^ only if you want to have each number on separate line
// you can replace with space or drop it entirely, if desired
Be aware that the algorithm, as is, prints out least significant bits first! You might want to have it inverse, then you'd either yet have to revert the string or (which I would prefer) start with writing the terminating 0 to the end and then fill up the digits one by one towards front - returning a pointer to the last digit (the most significant one) written instead of always the start of the buffer.
One word about your original version:
written = fwrite(p, sizeof(int), sizeof(p), infile);
sizeof(p) gives you the size of a pointer; this one is system dependent, but will always be the same on the same system, most likely 8 on yours (if modern 64-bit hardware), possibly 4 (on typical 32-bit CPU), other values on less common systems are possible as well. You'd need to return the number of characters printed separately (and no, sizeof(binaryNum) won't be suitable as it always returns 17, assuming 32-bit int and all changes shown above applied).
You probably want this:
...
int main()
{
int decimal = 2000;
int *p = decToBinary(decimal);
for (int i = 0; i< 16; i++)
{
printf("%d", p[i]);
}
return 0;
}
The output goes to the terminal instead into a file.
For writing into a file use fopen as in your code, and use fprintf instead of printf.
Concerning the decToBinary there is still room for improvement, especially you could transform the number directly into an array of char containing only chars 0 and 1 using the << and & operators.

print out a large number of integers rapidly in C

I have to print 1,000,000 four digit numbers. I used printf for this purpose
for(i=0;i<1000000;i++)
{
printf("%d\n", students[i]);
}
and it turns out to be too slow.Is there a faster way so that I can print it.
You could create an array, fill it with output data and then print out that array at once. Or if there is memory problem, just break that array to smaller chunks and print them one by one.
Here is my attempt replacing printf and stdio stream buffering with straightforward special-case code:
int print_numbers(const char *filename, const unsigned int *input, size_t len) {
enum {
// Maximum digits per number. The input numbers must not be greater
// than this!
# if 1
DIGITS = 4,
# else
// Alternative safe upper bound on the digits per integer
// (log10(2) < 28/93)
DIGITS = sizeof *input * CHAR_BIT * 28UL + 92 / 93,
# endif
// Maximum lines to be held in the buffer. Tune this to your system,
// though something on the order of 32 kB should be reasonable
LINES = 5000
};
// Write the output in binary to avoid extra processing by the CRT. If necessary
// add the expected "\r\n" line endings or whatever else is required for the
// platform manually.
FILE *file = fopen(filename, "wb");
if(!file)
return EOF;
// Disable automatic file buffering in favor of our own
setbuf(file, NULL);
while(len) {
// Set up a write pointer for a buffer going back-to-front. This
// simplifies the reverse order of digit extraction
char buffer[(DIGITS + 1 /* for the newline */) * LINES];
char *tail = &buffer[sizeof buffer];
char *head = tail;
// Grab the largest set of lines still remaining to be printed which
// will safely fit in our buffer
size_t chunk = len > LINES ? LINES : len;
const unsigned int *input_chunk;
len -= chunk;
input += chunk;
input_chunk = input;
do {
// Convert the each number by extracting least-significant digits
// until all have been printed.
unsigned int number = *--input_chunk;
*--head = '\n';
do {
# if 1
char digit = '0' + number % 10;
number /= 10;
# else
// Alternative in case the compiler is unable to merge the
// division/modulo and perform reciprocal multiplication
char digit = '0' + number;
number = number * 0xCCCDUL >> 19;
digit -= number * 10;
# endif
*--head = digit;
} while(number);
} while(--chunk);
// Dump everything written to the present buffer
fwrite(head, tail - head, 1, file);
}
return fclose(file);
}
I fear this won't buy you much more than a fairly small constant factor over your original (by avoiding some printf format parsing, per-character buffering, locale handling, multithreading locks, etc.)
Beyond this you may want to consider processing the input and writing the output on-the-fly instead of reading /processing/writing as separate stages. Of course whether or not this is possible depends entirely on the operation to be performed.
Oh, and don't forget to enable compiler optimizations when building the application. A run through with a profiler couldn't hurt either.

Resources