#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, n;
printf("\n%s\n%s",
"Some randomly distributed integers will be printed.",
"How many do yo want to see? ";
scanf("%d", &n);
for (i = 0; i < n; ++i) {
if (i % 10 == 0)
putchar('\n');
printf("%7d", rand());
}
printf("\n\n");
return 0;
}
this is the code from the textbook "A book on C".
when you type 23 when prompted it is supposed to generate 23 random numbers in 3 rows, 8 columns (3*8-1).
i learned that printf("%7d", rand())is supposed to return a value printed in a format of a decimal integer and the width of the field where the integer gets printed is 7.
however, I am getting random numbers that are in a width of more than 7 and it doesn't look neat at all. (no columns nor rows, just a huge chunk of consecutive numbers like 1235289043528935294835698246182965982)
I thought it has something to do with the expression printf("%7d", rand()) function and the way how it is supposed to return values.
I'm starting to think that the textbook is wrong.
Your numbers are bigger than 7 digits. You can try:
A) Changing the width field higher:
printf("%14d", rand() );
or
B) Making the generated numbers smaller than 7 digits:
printf("%7d", rand() % 1000 );
More information on format specifiers can be found here
Hope that helps!
You are not printing any whitespace. Try inserting some:
printf("%7d\t", rand());
In addition to the comment above, if I understand correctly you want all 8 numbers then the line should be changed to be: if (i % 8 == 0);
Rather than guess the maximum width of a rand() number, calculate the width of maximum random number: RAND_MAX.
snprintf(NULL, 0, ... prints the number of characters that would have been written had the buffer been sufficiently large, not counting the terminating null character.
int width = snprintf(NULL, 0, "%d", RAND_MAX);
Later when printing, use the width.
printf(" %*d", width, rand());
as in
#define COLUMN_N 8
for (i = 0; i < n; ++i) {
printf(" %*d", width, rand());
if (i % COLUMN_N == COLUMN_N - 1 || i + 1 == n) {
putchar('\n');
}
}
Related
I am writing a C program to get Fibonacci number, the user needs to put the first 2 numbers and the sequence starts from there. Here is my code:
#include <stdio.h>
#define MAX_SIZE 100
int main()
{
int i, input[MAX_SIZE];
printf("please Enter first 2 digit of the Sequence\n");
scanf("%d, %d" , &input[0], &input[1]);
for (i = 2; i < MAX_SIZE; i++)
{
input[i] = input[i-2] + input[i-1];
printf("%d\n", input[i]);
}
return 0;
}
But when i run the code with a input 2 and 3, I get a output like this 1499141456, which is clearly not the sequence. please help.
When you exit from the loop i is equal to MAX_SIZE
printf("%d\n", input[i]);
you are printing a value outside of the bounds of the array (input[MAX_SIZE]).
It's because the result in your code is bigger that the maximum value an int can handle
Live example here!
From Wikipedia
The number 2,147,483,647 (or hexadecimal 7FFF,FFFF16) is the maximum
positive value for a 32-bit signed binary integer in computing. It is
therefore the maximum value for variables declared as integers (e.g.,
as int) in many programming languages, and the maximum possible score,
money, etc. for many video games.
Here's where it goes wrong
[...]
433494437 + 701408733 = 1134903170
701408733 + 1134903170 = 1836311903
1134903170 + 1836311903 = -1323752223
put print statement inside for loop braces.
or (i = 2; i < MAX_SIZE; i++)
{
input[i] = input[i-2] + input[i-1];
printf("%d\n", input[i]);
}
Hello guys i am trying to implement a program which is finding the happy numbers were between two numbers A and B.
Summing the squares of all the digits of the number, we replace the number with the outcome, and repeat the process. If after some steps the result is equal to 1 (and stay there), then we say that the number N is **<happy>**. Conversely, if the process is repeated indefinitely without ever showing the number 1, then we say that the number N is **<sad>**.
For example, the number 7 is happy because the procedure described above leads to the following steps: 7, 49, 97, 130, 10, 1, 1, 1 ... Conversely, the number 42 is sad because the process leads to a infinite sequence 42, 20, 4, 16, 37, 58, 89, 145, 42, 20, 4, 16, 37 ...
I try this right down but i am getting either segm faults or no results.
Thanks in advance.
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
void happy( char * A, int n);
int numPlaces (long n);
int main(void)
{
long A,B;
int npA;
char *Ap;
printf("Give 2 Numbers\n");
scanf("%li %li",&A,&B);
npA = numPlaces(A);
Ap = malloc(npA);
printf("%ld %d\n",A,npA);
//Search for happy numbers from A to B
do{
sprintf(Ap, "%ld", A);
happy(Ap,npA);
A++;
if ( npA < numPlaces(A) )
{
npA++;
Ap = realloc(Ap, npA);
}
}while( A <= B);
}
//Finds happy numbers
void happy( char * A, int n)
{
//Basic Condition
if ( n == 1)
{
if (A[0] == 1 || A[0] == 7)
printf("%c\n",A[0]);
printf("%s\n",A);
return;
}
long sum = 0 ;
char * sumA;
int nsum;
int Ai;
//Sum the squares of the current number
for(int i = 0 ; i < n;i++)
{
Ai = atoi(&A[i]);
sum = sum + (Ai*Ai);
}
nsum = numPlaces (sum);
sumA = malloc(nsum);
sprintf(sumA, "%li", sum);
happy(sumA,nsum);
free(sumA);
}
//Count digits of a number
int numPlaces (long n)
{
if (n < 0) return 0;
if (n < 10) return 1;
return 1 + numPlaces (n / 10);
}
Thanks for your time.
by the definition of your program sad numbers will cause your program to run forever
Conversely, if the process is repeated indefinitely
You need to add a stopping condition, like if I have looped for 1000 times, or if you hit a well known non terminating number (like 4) (is there a definite list of these? I dont know)
I find this solution tested and working..
Thanks for your time and I am sorry for my vagueness.
Every advice about this solution would be welcome
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
void happy( char * A, int n);
int numPlaces (long n);
int happynum = 0;
int main(void)
{
long A,B;
int npA;
char *Ap;
printf("Give 2 Numbers\n");
scanf("%li %li",&A,&B);
npA = numPlaces(A);
Ap = malloc(npA);
//Search for happy numbers from A to B
do{
sprintf(Ap, "%ld", A);
happy(Ap,npA);
if (happynum ==1)
printf("%s\n",Ap);
A++;
if ( npA < numPlaces(A) )
{
npA++;
Ap = realloc(Ap, npA);
}
}while( A <= B);
}
//Finds happy numbers
void happy( char * A, int n)
{
//Basic Condition
if ( n == 1)
{
if (A[0] == '3' || A[0] == '6' || A[0] == '9')
{
happynum = 0;
}
else
{
happynum = 1;
}
return;
}
long sum = 0;
char * sumA;
int nsum;
int Ai;
//Sum the squares of the current number
for(int i = 0 ; i < n;i++)
{
Ai = (int)(A[i]-48);
sum = sum + (Ai*Ai);
}
nsum = numPlaces (sum);
sumA = malloc(nsum);
sprintf(sumA, "%li", sum);
happy(sumA,nsum);
free(sumA);
}
//Count digits of a number
int numPlaces (long n)
{
if (n < 0) return 0;
if (n < 10) return 1;
return 1 + numPlaces (n / 10);
}
Your code uses some questionable practices. Yoe may be misguided because you are concerned about performance and memory usage.
When you allocate memory for the string, you forget to allocate one character for the null terminator. But you shouldn't be allocating, re-allocating and freeing constantly anyway. Dynamic memory allocation is expensive compared to your other operations.
Your limits are long, which may be a 32-bit or 64-bit signed integer, depending on your platform. The maximum number that can be represented with e 64-bit signed integer is 9,223,372,036,854,775,807. This is a number with 19 digits. Add one for the null terminator and one for a possible minus sign, so that overflow won't hurt, you and use a buffer of 21 chars on the stack.
You probably shouldn't be using strings inthe first place. Use the basic code to extract the digits: Split off the digit by taking the remainder of a division by 10. Then divide by 10 until you get zero. (And if you use strings with a fixed buffer size, as described above, you don't have to calculate the difits separately: sprintf returns the number of characters written to the string.
Your functions shouldn't be recursive. A loop is enough. As pm100 has noted, you need a termination criterion: You must keep track of the numbers that you have already visited. Each recursive call creates a new state; it is easier to keep an array, that can be repeatedly looked at in a loop. When you see a number that you have already seen (other than 1, of course), your number is sad.
Happy and sad numbers have this property that when your sum of squares is a number with a known happiness, the original number has this happiness, too. If you visit a known das number, the original number is sad. If you visit a known happy number, the original number is happy.
The limits of your ranges may ba large, but the sum of square digits is not large; it can be at most the number of digits times 81. In particular:
type max. number number of max. square sum dss
int 2,147,483,647 1,999,999,999 730
uint 4,294,967,295 3,999,999,999 738
long 9,223,372,036,854,775,807 8,999,999,999,999,999,999 1522
ulong 18,446,744,073,709,55,1616 9,999,999,999,999,999,999 1539
That means that when you take the sum of digit squares of an unsigned long, you will get a number that is smaller than 1540. Create an array of 1540 entries and mark all known happy numbers with 1. Then you can reduce your problem to taking the sum of digit squares once and then looking up the happiness of the number in this array.
(You can do the precalculation of the array once when you start the program.)
The assignment is :
Write a program that calculates the sum of the divisors of a number from input.
A number is considered perfect if the sum of it's divisiors equal the number (ex: 6 = 1+2+3 ;28 = 1 + 2 + 4 + 7 +14).
Another definition:
a perfect number is a number that is half the sum of all of its positive divisors (including itself)
Generate the first k perfect numbers (k<150).
The main problem with this is that it's confusing the two asking points don't really relate.
In this program i calculated the sum of divisors of an entered number, but i don't know how to relate it with the second point (Generate the first k perfect numbers (k<150)).
#include <stdio.h>
#include <stdlib.h>
main()
{
int x,i,y,div,suma,k;
printf("Introduceti numarul\n"); \\enter the number
scanf("%d",&x);
suma=0; \\sum is 0
for(i=1;i<=x;i++)
{
if(x%i==0)
suma=suma+i; \\sum=sum+i;
}
printf("Suma divizorilor naturali este: %d\n",suma); \\the sum of the divisors is
for(k=1;k<150;k++) \\ bad part
{
if (x==suma)
printf("%d",k);
}
}
Suppose you have a function which can tell whether a given integer is perfect or not:
int isPerfect(int);
(function body not shown)
Now your main program will look like:
int candidate;
int perfectNumbers;
for(candidate = 1, perfectNumbers = 0; perfectNumbers < 150; candidate++) {
if (isPerfect(candidate)) {
printf("Number %d is perfect\n", candidate);
perfectNumbers++;
}
}
EDIT
For the same program without functions:
int candidate;
int perfectNumbers;
for(candidate = 1, perfectNumbers = 0; perfectNumbers < 150; candidate++) {
[... here your algorithm to compute the sum of the divisors of "candidate" ...]
if (candidate*2 == sum_of_divisors) {
printf("Number %d is perfect\n", candidate);
perfectNumbers++;
}
}
EDIT2: Just a note on perfect numbers
As noted in the comments section below, perfect numbers are very rare, only 48th of them are known as of 2014. The sequence (A000396) also grows very fast: using 64-bit integers you'll be able to compute up to the 8th perfect number (which happen to be 2,305,843,008,139,952,128). In this case the variable candidate will wrap around and start "finding" "new" perfect numbers from the beginning (until 150 of them are found: actually 19 repetitions of the only 8 findable in 64-bit integers). Note though that your algorithm must not choke on a candidate equals to 0 or to negative numbers (only to 0 if you declare candidate as unsigned int).
I am interpreting the question to mean generate all numbers under 150 that could are perfect numbers.
Therefore, if your program works for calculating perfect numbers, you keep calculating them until the starting number is >= 150.
Hope that makes sense.
Well, here's my solution ..
First, you have to make a reliable way of getting divisors.Here's a function I made for that:
size_t
getdivisors(num, divisors)
long long num;
long long *divisors;
{
size_t divs = 0;
for(long long i = num; i > 0; --i)
if (num%i == 0)
divisors[divs++] = i;
return divs;
}
Second, you need to check if the number's divisors match the perfect number's divisors properties (the sum of them is half the number).
Here's a second function for that:
bool
isperfect(num)
long long num;
{
long long divisors[num/2+1];
size_t divs = getdivisors(num, divisors);
if (divs == 0)
return false;
long long n = 0;
for(int i = 1; i < divs; ++i)
n += divisors[i];
return (n == num);
}
Now, from your question, I think you need to print all perfect numbers less than 150, right ?
See this:
int
main(argc, argv)
int argc;
char ** argv;
{
for(int i = 1; i < 150; ++i)
if (isperfect(i))
printf("%d is perfect.\n", i);
return 0;
}
I hope that answers your question ..
I am using the random() function, and I was wondering if there is a reason that I'm always getting 8-10 digit numbers. I just want to make sure there isn't something wrong with my program. Thanks.
Here's the function:
void random_array(int* p, int size) {
/*seed random number generator */
srandom(time(NULL));
int i;
for(i = 0; i < size; i++)
*(p+i) = random();
}
Well, mathematically the chance that you will get a big number is a lot more than the chance for a (relatively) small one. For instance, if you pick a random number with (1-4) digits, the chance that it would be in the range (0-99) would be only 1 %.
With that said, if you want smaller numbers, you can take the random modulo some certain number:
a = random() % 100; // this will give you a random number from 0 to 99
b = 10 + random() % 15; // random number from 10 to 24
Number of 8-10 digits numbers: 10,000,000,000 - 100,000,000 = 9,900,000,000 (9.9 billion)
Number of 0-7 digit numbers: 10,000,000 (10 million)
In other words, there are 990 8-10 digit numbers for every 1 0-7 digit number. Therefore, you can expect to get about 1 0-7 digit number for every 990 8-10 digit numbers.
Put simply, it's because there are more of them.
How large a number were you expecting to receive from random()?
If you want to limit the size of the number generated, simply use a modulus operator to limit the result to the remainder (in the example below a number from 0 to 999):
*(p+i) = random() % 1000;
Mathematically it is likely since big numbers are..well.. more than small ones, so yes. It is much more likely to get such a number.
To generate a custom-interval random number use something like
http://ideone.com/bWbBgJ
#include <stdlib.h>
#include <stdio.h>
// Generate random numbers in the min-max interval
void random_array(int* p, int size, int min, int max) {
/*seed random number generator */
srandom(time(NULL));
int i;
for(i = 0; i < size; i++)
*(p+i) = (random() % max) + min;
}
int main(void) {
int array[3];
random_array(array, 3, 0, 12);
printf("%d\n", array[0]);
printf("%d\n", array[1]);
printf("%d\n", array[2]);
return 0;
}
I would like to make the output of a number to always have 6 digits
e.g.:
if number is 1 the output should be 100000
if number is 23 the output should be 230000
if number is 236 the output should be 236000
How can I do this with printf/sprintf?
printf and its variants can pad zeroes to the left, not to the right. sprintf the number, then add the necessary zeros yourself, or make sure the number is 6 digits long:
while(num < 100000)
num *= 10;
(This code assumes the number isn't negative, or you're going to get in trouble)
printf will return the number of character printed out. This you can print out the remaining zeros:
int num = 3; // init
int len = printf("%d", num);
for (int i = 0; i < 6-len; ++i)
printf("0");
You should add some error checks (for example, if len is larger than 6).
With sprintf, you can use memset on the remaining buffer, which will be easier.
You can't do it directly with printf (at least in a standard-conforming way), you need to alter your numbers beforehand.
Use the return value of printf (as in the first line of the for loop below)
#include <stdio.h>
int main(void) {
int number, width = 6;
for (number = 1; number < 9999999; number *= 7) {
int digits = printf("%d", number);
if (digits < width) printf("%0*d", width-digits, 0);
puts("");
}
return 0;
}
See code running at http://ideone.com/TolIv
As Luchian said, this behavior is unsupported in printf, unlike the much more common reverse (left) padding.
You could, however, easily enough generate the requested result with something like this:
char *number_to_six_digit_string(char *resulting_array, int number)
{
int current_length = sprintf(resulting_array, "%d", number);
while (6 > current_length) {
resulting_array[current_length++] = '0';
}
resulting_array[current_length] = '\0';
return resulting_array;
}
and then you could print the result:
char my_number[7];
printf("my number is %s, other stuff\n", number_to_six_digit_string(my_number, 13));