Decimal to Binary conversion with quotient in C - c

I try to create a program which converts Decimal to Binary and back. My problem is when the fraction part becomes too big in binary, my program crashes. I tried many different approaches to this problem and none of them worked...I dont know why it happens so I have no sollution for it.
This program contains only the issue.
Please help me.
example1: 10 10.5 -> Program works fine
example2:10 10.23 -> Program crashes
Above are examples.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main(){
int base;
double number;
scanf("%d %lf",&base,&number);
if(base == 10){
//Integer Part
int n = (int)number;
number = number - (double)n;
int i = 0;
char *binaryfirst;
binaryfirst = malloc(sizeof(char*));
while(n != 0){
binaryfirst[i] = (n % 2) + '0';
n /= 2;
i++;
}
binaryfirst[i] = '\0';
strrev(binaryfirst);
//printf("%lf\n%s\n",number,binaryfirst);
//Fractional part
int j = 0;
char *binarysecond;
binarysecond = malloc(sizeof(char*));
//This is The part where I am lost...
for(j = 0; j < 60; j++){ //60 is the maximum length that it can become
number *= 2;
if(number >= 1.0){
binarysecond[j] = '1';
number = number - 1;
}else if(number == 0){
binarysecond[j] = '0';
break;
}else{
binarysecond[j] = '0';
}
printf("%lf; %c\n",number, binarysecond[j]);
}
printf("%d\n",j);
binarysecond[j] = '\0';
//printf("\n%s\n",binarysecond);
//Memory "Let it go"!!!!
/* for(i = 0; i < sizeof(binaryfirst); i++){
free(binaryfirst[i]*2);
}*/
free(binaryfirst);
/* for(j = 0; j < sizeof(binarysecond); j++){
free(binarysecond[j]);
}*/
free(binarysecond);
}
return 0;
}

This:
binaryfirst = malloc(sizeof(char*));
and
binarysecond = malloc(sizeof(char*));
allocates the size of a pointer, but the loop that writes to it makes it clear that it expects to store at most 60 bytes at that location. This makes no sense at all; C does not magically grow the allocation when you write outsite it, instead you get undefined behavior.
If you're unsure about heap memory allocations, and they're not crucial to the problem you're trying to solve, first do it without any. Just use simple arrays:
char binaryfirst64];
char binarysecond[64];

Related

I have troubles printing arrays of characters in C

the problem is that the following code prints nothing. And I tried very hard, using different methods, I used fixed sized arrays, I tried to print the array from a void function, I tried printf and sprintf, I tried with static s variable, I tried to loop the array and print charcacter the result is always the same, 0 errors, 0 warnings and never print the result. After about 30 seconds, the program automatically terminate with the following output:
Convert 56 to ascii:
Process returned -1073741819 (0xC0000005) execution time : 4.763 s
Press any key to continue.
Here's the code (I maybe used too many includes, but this is because I tried everything):
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void reverse(char s[])
{
int c, i, j;
for(i = 0, j = strlen(s)-1; i < j; i++,j++){
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
char * itoascii(int n)
{ char *s = malloc(10);
/*if(s == NULL)
return NULL;*/
int i, sign;
if((sign = n) < 0)
n = -n; // if n is negative, make it positive. And store the sign into sign
i = 0;
do {
s[i++] = n % 10 + '0'; // turn a digit into a string and then increment i
}while(( n /= 10) > 0);
if(sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
return s;
}
int main()
{ int n;
n = 56;
printf("Convert %d to ascii:\n", n);
char *buf = itoascii(n);
sprintf(buf, "%s\n");
return 0;
}
Yes, the problem was the y++ stuff. The fact is that I copied this code from a K&R edition with errata. In the book I found y++ and I blindy trusted the function, I never consider it in my debugging assuming the problem was due to improper pointer usage or other things.
Sure the code may be improved. printf es better than sprintf and I also must free the allocated memory with malloc. I also have to remove the extra unused include.
Thanks for your comments!
Code has at least these problems:
10 insufficient for large int. Suggest at least 12. Maybe sizeof(int)*CHAR_BIT/3 + 3 for an approximate generalization.
n = -n; is UB when n == INT_MIN.
Wrong increment
//for(i = 0, j = strlen(s)-1; i < j; i++,j++){
for(i = 0, j = strlen(s)-1; i < j; i++,j--){

Converting int to char

Task is to get int using scanf("%d") then print it again using printf("%с") without standard functions like atoi , itoa .As i understood i need to divide all numbers then add \0 char and print it, however how can i divide it. I thought about loop for dividing number%10 + /0 and number/10 to decrease number for 1 character .
Therefore code should look smoothing like this
#include <conio.h>
#include <stdio.h>
main(void)
{
int number,reserve ;
char Array[50];
scanf_s("%d",&number);
if (number > 0 || number == 0)
{
do
{
reserve = number % 10;
printf("%c", reserve + '/0');
number /= 10;
} while (number != 0);
}
else
{
number *= -1;
printf("-");
do
{
reserve = number % 10;
printf("%c", reserve + '/0');
number /= 10;
} while (number != 0);
}
_getch();
return 0;
}
As well there can be negative number so i need some if statement to check if it is negative and in case it is loop should avoid it it so we won't get smthing like -%10
So i don't know if loop is correct (hope someone will fix it and explain me how it is supposed to be). Waiting for your advices.
One side effect of the line
number = number % 10;
is that you lose the original value of number. So when you go to do
number = number/10;
it would always get the value zero. To fix this, store the original value somewhere else, or use another variable to do your character conversion (modulo 10, then plus \0).
Also, your loop needs to be re-examined. This process of modulo, add \0, divide, repeat, should stop when the result of the division is zero (i.e. there are no more digits to print). Another thing to think about is: in what order are these digits being printed?
I'll leave it to you to to figure out how to determine if the value of an int is greater than or less than zero, since you didn't attempt that in this snippet.
this will help you, adopt for your purposes
#include <stdio.h>
int main() {
int a;
int i = 0;
int str_size = 0;
char str[11] = {};
char tmp;
scanf("%d", &a);
while (a) {
str[str_size++] = a % 10 + '0';
a /= 10;
}
str_size--;
while (i < str_size) { // rewind
tmp = str[i];
str[i++] = str[str_size];
str[str_size--] = tmp;
}
printf("%s", str);
return 0;
}

error with array size

I am trying to make a program that calculates the amount of prime numbers that don't exceed an integer using the sieve of Eratosthenes. While my program works fine (and fast) for small numbers, after a certain number (46337) I get a "command terminated by signal 11" error, which I suppose has to do with array size. I tried to use malloc() but I didn't get it quite right. What shall I do for big numbers (up to 5billion)?
#include <stdio.h>
#include<stdlib.h>
int main(){
signed long int x,i, j, prime = 0;
scanf("%ld", &x);
int num[x];
for(i=2; i<=x;i++){
num[i]=1;
}
for(i=2; i<=x;i++){
if(num[i] == 1){
for(j=i*i; j<=x; j = j + i){
num[j] = 0;
}
//printf("num[%d]\n", i);
prime++;
}
}
printf("%ld", prime);
return 0;
}
Your array
int num[x];
is on the stack, where only small arrays can be accommodated. For large array size you'll have to allocate memory. You can save on memory bloat by using char type, because you only need a status.
char *num = malloc(x+1); // allow for indexing by [x]
if(num == NULL) {
// deal with allocation error
}
//... the sieve code
free(num);
I suggest also, you must check that i*i does not break the int limit by using
if(num[i] == 1){
if (x / i >= i){ // make sure i*i won't break
for(j=i*i; j<=x; j = j + i){
num[j] = 0;
}
}
}
Lastly, you want to go to 5 billion, which is outside the range of uint32_t (which unsigned long int is on my system) at 4.2 billion. If that will satisfy you, change the int definitions to unsigned, watching out that your loop controls don't wrap, that is, use unsigned x = UINT_MAX - 1;
If you don't have 5Gb memory available, use bit status as suggest by #BoPersson.
The following code checks for errors, tested with values up to 5000000000, properly outputs the final count of number of primes, uses malloc so as to avoid overrunning the available stack space.
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long int x,i, j;
unsigned prime = 0;
scanf("%lu", &x);
char *num = malloc( x);
if( NULL == num)
{
perror( "malloc failed");
exit(EXIT_FAILURE);
}
for(i=0; i<x;i++)
{
num[i]=1;
}
for(i=2; i<x;i++)
{
if(num[i] == 1)
{
for(j=i*i; j<x; j = j + i)
{
num[j] = 0;
}
//printf("num[%lu]\n", i);
prime++;
}
}
printf("%u\n", prime);
return 0;
}

Segmentation Fault during printing, includes large array computation

This program in C is supposed to delete every 666th number in a series of 10^7 natural numbers.
The problem seems to compile fine, even with optimisation. But, while on runtime stops throwing a Segmentation Fault after a few computations. I notice that when it stops its a few hundred thousand natural numbers away from the upper limit of 10^7. I at first tried to solve the problem using dynamic memory allocation with malloc. I received the same output. I tried using static arrays to do the job.
#include <stdio.h>
static unsigned int a[10000001] = {[0 ... 10000000] = 1};
void main(void) {
unsigned int i = 1, last = 0, count = 0, test = 0;
while(i < 100000) {
count = 0; test = 0;
while(count < 665) {
if(a[last + count + test])
count++;
else
test++;
}
last = last + test + count;
if(last < 10000002)
a[last] = 0;
else {
last = last - 10000001;
a[last] = 0;
}
printf(" %u", last);
i++;
}
printf("\n\n");
}
Here's one problem:
if(last < 10000002)
a[last] = 0;
Should be:
if(last < 10000001)
a[last] = 0;
Also, this statement might be an issue if last + count + test is > 10000000:
if(a[last + count + test])

Segmentation fault for prime generator

I am working on a small piece of code that generates all the primes between two numbers for a set. I decided to use a sieve (and i know theres probably a much more efficient way to do what I want than the way my code is using it) and for some reason I am getting a SIGSEGV (segmentation fault). I have looked over it quite a bit and I don't know what's wrong. I haven't been able to reproduce the error on my local machine. I get this error generally occurs when accessing out of bounds, but I don't know if thats the case here. Be Gentle, I am pretty new to C, always stuck to the higher level stuff.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char argv){
int numberOfSets;
scanf("%d", &numberOfSets);
int i;
int lowerBound, upperBound;
for(i=0; i < numberOfSets; i++){
scanf("%d %d", &lowerBound, &upperBound);
//allocating memory and initializing to Zero
int (*sieve) = malloc(sizeof(int) * (upperBound+1));
memset(sieve, 0, (sizeof(int) * (upperBound+1)));
//iterating through sieve for even numbers and marking them as non prime
int counter = 2;
if(sieve[counter] == 0)
sieve[counter] = 1;
int multiplier = 2;
int multiple = counter * multiplier;
while(multiple <= upperBound){
sieve[multiple] = -1;
multiplier++;
multiple = multiplier * counter;
}
//iterating through sieve (incrementing by two) and filling in primes up to upper limit
counter = 3;
while( counter <= upperBound){
if(sieve[counter] == 0)
sieve[counter] = 1;
multiplier = 2;
multiple = counter * multiplier;
while(multiple < upperBound){
sieve[multiple] = -1;
multiplier++;
multiple = multiplier * counter;
}
counter = counter + 2;
}
int newCount = lowerBound;
//check and print which numbers in the range are prime
while (newCount <= upperBound){
if(sieve[newCount] == 1)
printf("%d\n", newCount);
newCount=newCount+1;
}
//free the allocated memort
free(sieve);
}
}
The problem was that I was not checking the result of Malloc. I was attempting to allocate an array that was to large and the allocation was failing. This left the array I was assigning to null and thus I was accessing out of its bounds.

Resources