I'm writing a program that finds perfect numbers. Having read about these perfect numbers I came across a list of them: List of perfect numbers. At the moment the output is:
28 // perfect
496 // perfect
8128 // perfect
130816 // not perfect
2096128 // not perfect
33550336 // perfect
I decided to create array and put it with numbers, which divide the number wholly (without the rest). So I will be able to verify if it is a perfect number or not by adding all elements of the array. But app crashes and I cannot understand why:
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long number;
unsigned long arr2[100] = {0};
int k = 0;
for ( number = 0; number <= 130816; number++ )
if ( 130816 % number == 0 )
arr2[k++] = number;
for ( k = 0; k < 100; k++ )
printf("%lu", arr2[k]);
return 0;
}
You are doing modulus zero here:
if ( 130816 % number == 0 )
which is undefined behavior. If you start your for loop at 1 instead it should fix that issue. However, since N % 1 == 0 for all N, you probably need to start at 2.
From the C99 standard, 6.5.5 /5 (unchanged in C11):
The result of the / operator is the quotient from the division of the first operand by the
second; the result of the % operator is the remainder. In both operations, if the value of
the second operand is zero, the behavior is undefined.
You are dividing by zero when number=0;
138816 % number involves division and a remainder.
Related
I have a tricky requirement in project asking to write function which returns a value 1 (0 otherwise) if given an integer representable as 22n+1. Where n is any non-negative integer.
int find_pow_2n_1(int M);
for e.g: return 1, when M=5 since 5 is output when n=1 -> 21*2+1 .
I am trying to evaluate the equation but it results in log function, not able to find any kind of hint while browsing in google as well .
Solution
int find_pow_2n_1(int M)
{
return 1 < M && !(M-1 & M-2) && M % 3;
}
Explanation
First, we discard values less than two, as we know the first matching number is two.
Then M-1 & M-2 tests whether there is more than one bit set in M-1:
M-1 cannot have zero bits set, since M is greater than one, so M-1 is not zero.
If M-1 has one bit set, then that bit is zero in M-2 and all lower bits are set, so M-1 and M-2 have no set bits in common, so M-1 & M-2 is zero.
If M-1 has more than one bit set, then M-2 has the lowest set bit cleared, but higher set bits remain set. So M-1 and M-2 have set bits in common, so M-1 & M-2 is non-zero.
So, if the test !(M-1 & M-2) passes, we know M-1 is a power of two. So M is one more than a power of two.
Our remaining concern is whether that is an even power of two. We can see that when M is an even power of two plus one, its remainder modulo three is two, whereas when M is an odd power of two plus one, its remainder modulo three is zero:
Remainder of 20+1 = 2 modulo 3 is 2.
Remainder of 21+1 = 3 modulo 3 is 0.
Remainder of 22+1 = 5 modulo 3 is 2.
Remainder of 23+1 = 9 modulo 3 is 0.
Remainder of 24+1 = 17 modulo 3 is 2.
Remainder of 25+1 = 33 modulo 3 is 0.
…
Therefore, M % 3, which tests whether the remainder of M modulo three is non-zero, tests whether M-1 is an even power of two.
There are only a few numbers with that property: make a table lookup array :-)
$ bc
for(n=0;n<33;n++)2^(2*n)+1
2
5
17
65
257
1025
4097
16385
65537
262145
1048577
4194305
16777217
67108865
268435457
1073741825
4294967297
17179869185
68719476737
274877906945
1099511627777
4398046511105
17592186044417
70368744177665
281474976710657
1125899906842625
4503599627370497
18014398509481985
72057594037927937
288230376151711745
1152921504606846977
4611686018427387905
18446744073709551617
Last number above is 2^64 + 1, probably will not fit an int in your implementation.
All proposed solutions are way too complicated or bad in performance. Try the simpler one:
static int is_power_of_2(unsigned long n)
{
return (n != 0 && ((n & (n - 1)) == 0));
}
static int is_power_of_2n(unsigned long n)
{
return is_power_of_2(n) && (__builtin_ffsl(n) & 1);
}
int main(void)
{
int x;
for (x = -3; x < 20; x++)
printf("Is %d = 2^2n + 1? %s\n", x, is_power_of_2n(x - 1) ? "Yes" : "no");
return 0;
}
Implementing __builtin_ffsl(), if you are using ancient compiler, I leave it as a homework (it can be done without tables or divisions).
Example: https://wandbox.org/permlink/gMrzZqhuP4onF8ku
While commenting on #Lundin's comment I realized that you may read a very nice set of bit twiddling hacks from Standford University.
UPDATE. As #grenix noticed the initial question was about the direct check, it may be done with the above code by introducing an additional wrapper, so nothing basically changes:
...
static int is_power_of_2n_plus_1(unsigned long n)
{
return is_power_of_2n(n - 1);
}
int main(void)
{
int x;
for (x = -3; x < 20; x++)
printf("Is %d = 2^2n + 1? %s\n", x, is_power_of_2n_plus_1(x) ? "Yes" : "no");
return 0;
}
Here I am leaving you a pseudocode (or a code that I haven't tested) which I think could help you think of the way to handle your problem :)
#include <math.h>
#include <stdlib.h>
#define EPSILON 0.000001
int find_pow_2n_1(int M) {
M--; // M = pow 2n now
double val = log2(M); // gives us 2n
val /= 2; // now we have n
if((val * 10) / 10 - val) <= EPSILON) return 1; // check whether n is an integer or not
else return 0;
}
So I have this factorial function written in C:
unsigned int factorial(unsigned int n){
int fn = 1;
if(n == 0 || n == 1){
return 1;
} else{
for(int i = 1; i <= n; i++){
fn *= i;
}
}
return fn;
}
I tested it out with smaller numbers like 5 and it worked. Then I put it into this loop:
for(int i = 0; i < 100; i++){
printf("\n%d! = %d", i, factorial(i));
}
When i reaches 17, the factorial is apparently -288522240 which is obviously wrong. These kinds of answers continue until i reaches 34 and it says that the factorial is 0. It then does this for the rest of the numbers.
I don't understand what's wrong with my code. I see no reason for the number to become negative or 0. What's happened here?
100! or 9.3326...E+157 or
9332621544394415268169923885626670049071596826438162146859296389521759999322991560894146397615651828625369792082722375825118521091686400000000000000000000000, a 525 bit number, is outside the range of int - likely 32-bit [-2147483648 ... 2147483647]
Signed integer math that overflows is undefined behavior (UB). In OP's case, it appears that the lower 32-bits of the product fn * i, as 2's complement, was the result. Eventually enough multiplication of even numbers kept shifting the non-zero portion of the product "to the left" and resulted in that lower 32 bits becoming 0.
To calculate large factorials one needs another approach. Example
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
So I have some code here that I have been studying. It converts decimal numbers to binary. The code runs smoothly but what's bugging me are the variables. The code is as follows:
#include <stdio.h>
int main()
{
long int decimalNumber, remainder, quotient;
int binaryNumber[100], i=1, j;
printf("Enter any decimal number: ");
scanf("%ld",&decimalNumber);
quotient = decimalNumber;
while (quotient!=0) {
binaryNumber[i++]= quotient % 2;
quotient = quotient / 2;
}
printf("Equivalent binary value of decimal number %d: ", decimalNumber);
for (j = i -1 ; j> 0; j--)
printf("%d",binaryNumber[j]);
return 0;
}
I really find the variables confusing. Can someone tell me what is actually happening with the variables? Especially the one with binaryNumber[100],binaryNumber[i++], binaryNumber[j], and the expression binaryNumber[i++] = quotient % 2
binaryNumber is an array of ints, i.e. of integers. It is of size 100. It goes from 0...99 (binaryNumber[0] is the first element and binaryNumber[99] is the last). The array can contain 100 integers, of different or equal values. They don't actually have to be of value 0...99 but anything else that is in the range of int (read comment).
When you perform int binaryNumber[100] you define this array.
When you perform binaryNumber[i++] you access the element in the location i of this array, and then increment i. Meaning you perform i = i + 1;.
Same goes for binaryNumber[j].
When you perform binaryNumber[i++] = quotient % 2 you assign the value of quotient % 2 to the binaryNumber array at position i like stated before (and increment i).
If you're wondering about the modulus operator (%) read here.
binaryNumber[100]: This is actually an array of 100 integers. The first integer in the array could be accessed by binaryNumber[0] etc.
binaryNumber[j]: This means the (j-1)th integer in the array.
binaryNumber[i++]: Lets say i=3 when this statement runs. binaryNumber[i++] is equivalent to binaryNumber[3], which is the 4th integer. However, after this statement is executed, i is incremented to 4.
quotient % 2:
% is actually the modulus operator. Example: 13 % 4 = remainder of 13/4 = 1.
binaryNumber[100] : it is an array , a sepuence of elements of type "long int" you can access a spesific element using "array[index] = value" .
binaryNumber[i++] : access the element nember i then increament i , example if i=1 then you acces binaryNumber[1] then i become 2 (after usage ).
binaryNumber[j] : access the element nember j , j is a variable and can be used as a index , then you will acces the element nember the current value of j .
binaryNumber[i++] = quotient % 2 : it tell the compiler to let the element nember i in the binaryNumber take the value of quotient % 2 that is the math modulos , like 9%2=1 ; 5%3=2 , the rest of the quotient pear 2
comment for more informations .
A simple way to do the conversion is a loop and shift. You can put it in a function to make the conversion look nice. Here is an example:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> /* for CHAR_BIT */
void binprn (const unsigned long v);
int main (int argc, char **argv) {
long unsigned a = argc > 1 ? strtoul (argv[1], NULL, 10) : 4327;
printf ("\n %lu decimal, binary: ", a);
binprn (a);
putchar ('\n');
return 0;
}
/** unpadded binary representation of 'v'. */
void binprn (const unsigned long v)
{
if (!v) { putchar ('0'); return; };
size_t sz = sizeof v * CHAR_BIT;
unsigned long rem = 0;
while (sz--)
if ((rem = v >> sz))
putchar ((rem & 1) ? '1' : '0');
}
Use/Output
$ ./bin/dec2bin
4327 decimal, binary: 1000011100111
$ ./bin/dec2bin 10
10 decimal, binary: 1010
$ ./bin/dec2bin 127
127 decimal, binary: 1111111
This is a program to find number of digits.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int i = 0, n;
printf("Enter number: ");
scanf("%d", &n);
while ((n / pow(10, i)) != 0) {
i++;
}
printf("%d", i);
}
This program gives 309 as the output (value of i) on any input. However, if I store the value of pow(10, i) in another variable and put it in while loop, I get the correct output. Please help!
C++ uses the most precise type (when types are mixed) when doing a calculation or evaluation, and here you are effectively mixing a double with an int. You are dividing a user input number by a very large exponential number.
This in theory will never be zero, no matter how big the divisor gets. So, the theoretical result should be infinite. However, due to the limits of a double (which is returned by pow), it will still eventually approximate zero.
If you store the return of pow in an integer, you will no longer be mixing types and will effectively be working out the number of digits or what the approximate log base 10 is (any integer divide by a larger integer will equal zero).
Change:
while( ( n / pow(10,i) )!=0 ){
To:
while( ( n / pow(10,i) ) >= 1 ){
pow returns double and therefore the full result is double and the fractional part will be always non-zero until running out of exponent possible values which is 309 (translated to decimal, binary is 1024).
I have a homework. The question is:
Write a function that takes as parameter a single integer, int input, and returns an unsigned character
such that:
a- if input is negative or larger than 11,111,111 or contains a digit that is not 0 or 1; then the function will
print an error message (such as “invalid input”) and return 0,
b- otherwise; the function will assume that the base-10 value of input represents a bit sequence and return the magnitude-only bit model correspondent of this sequence.
For Example: If input is 1011, return value is 11 and If input is 1110, return value is 14
This is my work for a, and I am stuck on b. How can I get bit sequence for given integer input?
int main()
{
int input = 0;
printf("Please type an integer number less than 11,111,111.\n");
scanf("%d",&input);
if(input < 0 || input > 11111111)
{
printf("Invalid Input\n");
system("PAUSE");
return 0;
}
for (int i = 0; i < 8; i++)
{
int writtenInput = input;
int single_digit = writtenInput%10;
if(single_digit == 0 || single_digit == 1)
{
writtenInput /= 10;
}
else
{
printf("Your digit contains a number that does not 0 or 1. it is invalid input\n");
system("PAUSE");
return 0;
}
}
printf("Written integer is %d\n",input);
system("PAUSE");
return 0;
}
The bit that you are missing is the base conversion. To interpret a number in base B, what you need to do is multiply digit N times B^N (assuming that you start counting digits from the least significative). For example, in base 16, A108 = (10)*16^3 + 1*16^2 + 0*16^1 + 8*16^0. Where in your base is 2 (binary).
Alternatively, you can avoid the exponentiation if you rewrite the expression as:
hex A008 = ((((10*16) + 1)*16 +0)*16 + 8
Which would be simpler if your input was stated in terms of an array of possibly unknown length as it is easily convertible into a loop of only additions and multiplications.
In the particular case of binary, you can use another direct solution, for each digit that is non-zero, set the corresponding bit in an integer type large enough (in your case, unsigned char suffices), and the value of the variable at the end of the loop will be the result of the conversion.
First off, the existing part of your code needs work. It doesn't report non-binary digits correctly. The question is "Are there any digits that are neither 0 nor 1". To answer this question in the negative, you need to check every single digit. Your code can terminate early. I also suggest renaming the function to something that clearly tells you what it does. For example haveNonBinaryDigit. The term check doesn't tell you what you should expect on the return value.
As for the second part, read up on the binary representation. It is fairly similar to decimal, except that instead of each digit being weighted by 1, 10, 100, .., 10^x, they are weighted by 1, 2, 4, ..., 2^n. Also the digits can only have values 0 and 1.
Your current code has a problem: it will terminate as soon as it finds one single binary bit (at the end) and call the entire integer correct.
I would take a different approach to this problem. What you want to do is get your hands on every single digit from the integer seperately. You made a good start in doing so by using modulo. Say you had this code:
for (int i = 0; i < 8; i++)
{
char single_digit = input%10;
input /= 10;
}
This makes it easy to start working with the digits. You would be checking 8 bits because that seems to be the maximum allowed (11,111,111). Check if each digit is either 0 or 1. Then you can start pushing it in to an unsigned character using bitwise operations. Shift every digit to the left by i, then use a bitwise OR.