Why is my to_base_n Program not working? - c

I need to write a C program which will read a number (in base 10) from user input and output it in any base which is a power of 2. The calculations have to be performed in one function, to_base_n, which takes the parameters num and base and prints the number in the respective base. As a validation check, the program also checks if the base is a power of two with the isPowerofTwo function.
The way the conversion is carried out is by means of long division which carries out the logic in the pseudocode below:
void to_base_n(int x, int n){
int r, i = 0
int digits[16]
while (x ≠ 0){
r = x mod n
x = x / n
digits[i] = r
i++
}
for (i = 0, i < 15, i++)
print digits[i]
}
Which I believe is arithmetically sound. But when I try to, for example, convert 82000 to base 4, I get the following output:
The large digits appearing are even bigger than num itself, so I figured the modulus cannot be entering the array properly (because ∀{x,n}; x mod n < x). I can't seem to find what's wrong with it. The full code is listed below.
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
bool isPowerofTwo(int);
void to_base_n(int, int);
int main(){
//Variables
int num, base;
//Prompt
printf("Please enter a number in base 10: ");
scanf("%d", &num);
printf("Please enter a base (2^n) to convert it to: ");
scanf("%d", &base);
//Precaution
while(!isPowerofTwo(base)){
printf("That number is not a power of 2. Please try again: ");;
scanf("%d", &base);
}
if(isPowerofTwo(base)){
//Output
printf("The number %d (base 10) is equivalent to ", num);
to_base_n(num, base);
printf(" (base %d).", base);
}
//Return Statement
return 0;
}
//Checks if Base is a Power of Two
bool isPowerofTwo(int base){
while((base % 2 == 0) && base > 1){
base = base / 2;
if(base == 1){
return true;
break;
}
}
return false;
}
//to_base_n
void to_base_n(int x, int n){
int r, i = 0;
int digits[16];
while(x != 0){
r = x % n;
x = x / n;
digits[i] = r;
i++;
}
for(i = 0; i < 15; i++)
printf("%d|",digits[i]);
}
Can anyone help explain what's wrong with it?

The number 82000 in base 4 would be:
110001100
Which is exacly what you get. Your mistake is that:
They are printed backwards.
You are printing more digits than you should, so you print garbage.

You ignore the number of digits extracted with your pseudo code, so you print uninitialised elements of the array.
for (i = 0, i < 15, i++)
print digits[i]
And they are printed in reverse order. I suggest changing it to this
for (i = i - 1, i >= 0, i--)
print digits[i]
and as C code in your function
for(i = i - 1; i >= 0; i--)
printf("%d|",digits[i]);

Related

Is float always rounding?

Here is my program, it turn decimal to base-"n", you can put number in "n" base what you want to turn to, it run successful but I have a question, I don't get it why the if ((float)input / (float)n <= 0) can pass in the fifth time. I'm debugging with vscode and watch the value every breakpoints and steps, here are the result
(run this line if ((float)input / (float)n <= 0))
input=20, n=2
First time : 20/2=10 (pass)
Second time : 10/2=5 (pass)
Third time : 5/2=2.5 (pass)
Forth time : 2.5/2=1 (pass) I don't understand why it is "1" not "1.25" (I think this is my main problem, is float always rouding ?)
Fifth time : 1/2=0.5 (pass)
Sixth time : 0.5/2=0 (fail and break)
Hope somebody can explain that I'll very appreciate, English not my mother tongue so forgive me.
#include <stdio.h>
#include <stdlib.h>
void rev(int num[]);
int cnt = 0;
int main()
{
int input = 20, num[10], i, n = 2;
// Decimal turn to base-n
printf("Decimal \"%d\" to base-%d = ", input, n);
for (i = 0; i < 10;)
{
if ((float)input / (float)n <= 0)
break;
else
{
num[i] = input % n;
input /= n;
i++;
cnt++;
}
}
rev(num);
printf("\n");
system("pause");
return 0;
}
void rev(int num[])
{
int i;
i = cnt - 1;
for (i; i >= 0; i--)
printf("%d", num[i]);
}
absolutely will be fail because . when you type casting float to int like int a = 3.14 ; just the decimal part will be stored exp int a = 0.5; means a equal to 0 .
When you divide input by n, you're doing integer division:
input /= n;
Integer division has an integer result. And either way, you're storing the result back to an integer, so any fractional portion is discarded.
So the values stored in input each time through the loop will be 20, 10, 5, 2 (not 2.5), 1, and 0.

Rounding off an integer to always end on 0

I'm making a program to calculate the number of perfect squares between 1 and another number, and I want the counter to take only the first number of the integer, and put 0 on the rest, e.g: Result of the calculation is 31, I want to display 30, if it's 190, then display 100, and so on.
int number;
int i = 1;
int perfectCounter = 0;
printf("Enter a number: ");
scanf("%d", &number);
while (i <= number) {
float tempSquare = sqrt(i);
int integerPart = tempSquare;
if (tempSquare == integerPart)
perfectCounter++;
i++;
}
printf("%d", perfectCounter);
That's the code that I have right now, if I insert 1000, it will display 31, and I want it to display 30, I can't think a solution for this.
Divide the number by the highest power of 10 below the number. Do this using integer arithmetic, so it gets the integer part of the division. Then multiply by the power of 10.
#include <math.h>
int powerOf10 = pow(10, (int)log10(perfectCounter));
int roundedCounter = (perfectCounter/powerOf10)*powerOf10;
printf("%d", roundedCounter);
You can use a function like this one to round your numbers. Basically what it does is it "chips away" one digit at a time until we are left with only one digit and then adds appropriate number of zeros to it:
int round(int _in){
int numDigits = 0;
while(_in > 9){
++numDigits;
_in /= 10;
}
int res = _in; // whatever is left would be the left-most digit
for(int i = 0; i < numDigits; ++i){
res *= 10;
}
return res;
}
Here's a simple solution with no math:
void print_rounded(int i) {
unsigned u = i;
if (i < 0) { putchar('-'); u = -i; }
char buf[2];
int n = snprintf(buf, 2, "%u", u);
for (putchar(buf[0]); --n; putchar('0')) {}
}
(In other words, print the first digit, and then print enough 0's to make up the length of the original number.)

How to check whether a no is factorial or not?

I have a problem, then given some input number n, we have to check whether the no is factorial of some other no or not.
INPUT 24, OUTPUT true
INPUT 25, OUTPUT false
I have written the following program for it:-
int factorial(int num1)
{
if(num1 > 1)
{
return num1* factorial(num1-1) ;
}
else
{
return 1 ;
}
}
int is_factorial(int num2)
{
int fact = 0 ;
int i = 0 ;
while(fact < num2)
{
fact = factorial(i) ;
i++ ;
}
if(fact == num2)
{
return 0 ;
}
else
{
return -1;
}
}
Both these functions, seem to work correctly.
When we supply them for large inputs repeatedly, then the is_factorial will be repeatedly calling factorial which will be really a waste of time.
I have also tried maintaining a table for factorials
So, my question, is there some more efficient way to check whether a number is factorial or not?
It is wasteful calculating factorials continuously like that since you're duplicating the work done in x! when you do (x+1)!, (x+2)! and so on.
One approach is to maintain a list of factorials within a given range (such as all 64-bit unsigned factorials) and just compare it with that. Given how fast factorials increase in value, that list won't be very big. In fact, here's a C meta-program that actually generates the function for you:
#include <stdio.h>
int main (void) {
unsigned long long last = 1ULL, current = 2ULL, mult = 2ULL;
size_t szOut;
puts ("int isFactorial (unsigned long long num) {");
puts (" static const unsigned long long arr[] = {");
szOut = printf (" %lluULL,", last);
while (current / mult == last) {
if (szOut > 50)
szOut = printf ("\n ") - 1;
szOut += printf (" %lluULL,", current);
last = current;
current *= ++mult;
}
puts ("\n };");
puts (" static const size_t len = sizeof (arr) / sizeof (*arr);");
puts (" for (size_t idx = 0; idx < len; idx++)");
puts (" if (arr[idx] == num)");
puts (" return 1;");
puts (" return 0;");
puts ("}");
return 0;
}
When you run that, you get the function:
int isFactorial (unsigned long long num) {
static const unsigned long long arr[] = {
1ULL, 2ULL, 6ULL, 24ULL, 120ULL, 720ULL, 5040ULL,
40320ULL, 362880ULL, 3628800ULL, 39916800ULL,
479001600ULL, 6227020800ULL, 87178291200ULL,
1307674368000ULL, 20922789888000ULL, 355687428096000ULL,
6402373705728000ULL, 121645100408832000ULL,
2432902008176640000ULL,
};
static const size_t len = sizeof (arr) / sizeof (*arr);
for (size_t idx = 0; idx < len; idx++)
if (arr[idx] == num)
return 1;
return 0;
}
which is quite short and efficient, even for the 64-bit factorials.
If you're after a purely programmatic method (with no lookup tables), you can use the property that a factorial number is:
1 x 2 x 3 x 4 x ... x (n-1) x n
for some value of n.
Hence you can simply start dividing your test number by 2, then 3 then 4 and so on. One of two things will happen.
First, you may get a non-integral result in which case it wasn't a factorial.
Second, you may end up with 1 from the division, in which case it was a factorial.
Assuming your divisions are integral, the following code would be a good starting point:
int isFactorial (unsigned long long num) {
unsigned long long currDiv = 2ULL;
while (num != 1ULL) {
if ((num % currDiv) != 0)
return 0;
num /= currDiv;
currDiv++;
}
return 1;
}
However, for efficiency, the best option is probably the first one. Move the cost of calculation to the build phase rather than at runtime. This is a standard trick in cases where the cost of calculation is significant compared to a table lookup.
You could even make it even mode efficient by using a binary search of the lookup table but that's possibly not necessary given there are only twenty elements in it.
If the number is a factorial, then its factors are 1..n for some n.
Assuming n is an integer variable, we can do the following :
int findFactNum(int test){
for(int i=1, int sum=1; sum <= test; i++){
sum *= i; //Increment factorial number
if(sum == test)
return i; //Factorial of i
}
return 0; // factorial not found
}
now pass the number 24 to this function block and it should work. This function returns the number whose factorial you just passed.
You can speed up at least half of the cases by making a simple check if the number is odd or even (use %2). No odd number (barring 1) can be the factorial of any other number
#include<stdio.h>
main()
{
float i,a;
scanf("%f",&a);
for(i=2;a>1;i++)
a/=i;
if(a==1)
printf("it is a factorial");
else
printf("not a factorial");
}
You can create an array which contains factorial list:
like in the code below I created an array containing factorials up to 20.
now you just have to input the number and check whether it is there in the array or not..
#include <stdio.h>
int main()
{
int b[19];
int i, j = 0;
int k, l;
/*writing factorials*/
for (i = 0; i <= 19; i++) {
k = i + 1;
b[i] = factorial(k);
}
printf("enter a number\n");
scanf("%d", &l);
for (j = 0; j <= 19; j++) {
if (l == b[j]) {
printf("given number is a factorial of %d\n", j + 1);
}
if (j == 19 && l != b[j]) {
printf("given number is not a factorial number\n");
}
}
}
int factorial(int a)
{
int i;
int facto = 1;
for (i = 1; i <= a; i++) {
facto = facto * i;
}
return facto;
}
public long generateFactorial(int num){
if(num==0 || num==1){
return 1;
} else{
return num*generateFactorial(num-1);
}
}
public int getOriginalNum(long num){
List<Integer> factors=new LinkedList<>(); //This is list of all factors of num
List<Integer> factors2=new LinkedList<>(); //List of all Factorial factors for eg: (1,2,3,4,5) for 120 (=5!)
int origin=1; //number representing the root of Factorial value ( for eg origin=5 if num=120)
for(int i=1;i<=num;i++){
if(num%i==0){
factors.add(i); //it will add all factors of num including 1 and num
}
}
/*
* amoong "factors" we need to find "Factorial factors for eg: (1,2,3,4,5) for 120"
* for that create new list factors2
* */
for (int i=1;i<factors.size();i++) {
if((factors.get(i))-(factors.get(i-1))==1){
/*
* 120 = 5! =5*4*3*2*1*1 (1!=1 and 0!=1 ..hence 2 times 1)
* 720 = 6! =6*5*4*3*2*1*1
* 5040 = 7! = 7*6*5*4*3*2*1*1
* 3628800 = 10! =10*9*8*7*6*5*4*3*2*1*1
* ... and so on
*
* in all cases any 2 succeding factors inf list having diff=1
* for eg: for 5 : (5-4=1)(4-3=1)(3-2=1)(2-1=1)(1-0=1) Hence difference=1 in each case
* */
factors2.add(i); //in such case add factors from 1st list " factors " to " factors2"
} else break;
//else if(this diff>1) it is not factorial number hence break
//Now last element in the list is largest num and ROOT of Factorial
}
for(Integer integer:factors2){
System.out.print(" "+integer);
}
System.out.println();
if(generateFactorial(factors2.get(factors2.size()-1))==num){ //last element is at "factors2.size()-1"
origin=factors2.get(factors2.size()-1);
}
return origin;
/*
* Above logic works only for 5! but not other numbers ??
* */
}

First real program in C: Fibonacci sequence

I'm trying to write the first 10 terms of the Fibonacci sequence. I feel like I'm on the right line, but I can't seem to quite grasp the actual code (in C).
float fib = 0;
const float minn = 1;
const float maxn = 20;
float n = minn;
while (n <= maxn);{
n = n + 1;
printf (" %4,2f", fib);
fib = (n - 1) + (n - 2);
}
With the fibonacci sequence the value f(n) = f(n - 1) + f(n = 2). the first three values are defined as 0, 1, 1.
The fibonacci sequence is a sequence of integer values (math integers, not necessarily C language values). consider using int or long for the fibonacci value. float is worthless, it only adds unneeded overhead.
when calculating the fibonacci sequence you must store the previous 2 values to get the next value.
you want 10 fibonacci values. you know the first three already so print those and then calculate the next seven values.
7 values implies a loop that iterates 7 times. it has no bearing on the maximum value of the fibonacci value returned, just how many values you want to print.
do something like this:
printf("0, 1, 1");
int currentValue;
int valueN1 = 1;
int valueN2 = 1;
for (int counter = 1; counter <= 7; ++counter)
{
currentValue = valueN1 + valueN2;
printf(", %d", currentValue);
valueN2 = valueN1;
valueN1 = currentValue;
}
You need run loop 10 times only,to find first 10 terms of the Fibonacci sequence.
in your code,while loop would not let you go further because of semicolon at the end of loop
//declare fib value as long int or unsigned int
// because the value of any fib term is not at all
long int fib;
int n=1;
while (n <= 10)
{
printf (" %d", fib);
fib = fib_term(n);
n = n + 1;
}
implement fib_term(int n); by seeing this snippet
First off, I would suggest changing your datatype from a float to an integer or other datatype. floats are not exact numbers and if you had used while (n = maxn) instead of while (n <= maxn) you could have ended up with an infinite loap since the two floats would never have matched.
Second, you don't seem to really understand what the fibonacci sequence is. Take a look at the wikipedie article http://en.wikipedia.org/wiki/Fibonacci_number.
The fibinocci number is NOT (n - 1) + (n - 2) like you have. It is the sum of the previous two numbers in the sequence. You need to restructure your loop to hold the last two values and calculate the next one based on these values.
There are (at least) 2 ways to implement the Fibonacci Algorithm in C:
The Iterative:
int fib(int n){
if (n == 0)
return 0;
int a = 1
int b = 1;
for (int i = 3; i <= n; i++) {
int c = a + b;
a = b;
b = c;
}
return b;
}
The Recursive:
unsigned int fibonacci_recursive(unsigned int n)
{
if (n == 0)
{
return 0;
}
if (n == 1) {
return 1;
}
return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2);
}
void main(){
unsigned int i = fibonacci_recursive(10);
}
Suggestions
Consider integer types before FP types when doing integer problems.
Omit a ; in your while (n <= maxn);{
Use a . in floating point formats %4.2f instead of %4,2f.
Fibonacci is the sum of the previous 2 terms, not simply fib = (n - 1) + (n - 2).
Consider an unsigned solution:
C code:
void Fibonacci_Sequence(unsigned n) {
const unsigned minn = 1;
const unsigned maxn = 20;
unsigned F[3];
F[0] = 0;
F[1] = 1;
unsigned i = 0;
for (i = 0; i <= maxn; i++) {
if (i >= minn) printf(" %u,", F[0]);
F[2] = F[1] + F[0];
F[0] = F[1];
F[1] = F[2];
}
}
This uses n/2 iterations
#include<stdio.h>
main()
{
int i,n,a=0,b=1,odd;
scanf("%d",&n);
odd=n%2;
for(i=1;i<=n/2;i++)
{
printf("%d %d ",a,b);
a=a+b;
b=a+b;
}
if(odd)
printf("%d",a);
}

Recursion, possible error in algo

i am doing one of the simple programin C, sum of digits of 5 digit number.Though i had done it using a simple function but i need to do it with recursion also.I had read many solution on net regarding this problem using recursion and had implemented one of mine.But that is giving error and i cant figure out what mesh i am doing in my algo.
#include<stdio.h>
int sum5(int x); //function for sum of digits of 5 digit number
int main()
{
int x;
int result;
printf("Enter a 5 digit number : ");
scanf("%d",&x);
printf("Number entered by you is %d",x);
result = sum5(x);
printf("Sum of digits of 5 digit number is = %d",&result);
return 0;
}
int sum5(int x)
{
int r;
int sum=0;
if(x!=0){
r=x%10;
sum=sum+r;
x=x-r; //doing this so that 0 come in the last and on diving it by 10, one digit will be removed.
sum5(x/10);
}
return sum;
}
but after its execution i am getting wrong result.It is dumping some anonymous value on the output.
Also, your sum5 function is incorrect. You have to add the value of sum5 to the sum variable of the caller function.
int sum5(int x)
{
int r;
int sum = 0;
if (x != 0) {
r = x % 10;
sum = r;
//x = x - r; - this isn't required. integer division will floor x
sum += sum5(x / 10);
}
return sum;
}
This is incorrect as it is printing the address of result and not its value:
printf("Sum of digits of 5 digit number is = %d",&result);
Change to:
printf("Sum of digits of 5 digit number is = %d", result);
Always check the result of scanf() to ensure a valid value was read:
/* Returns number of assignments made. */
if (scanf("%d", &x) == 1 && x > 9999 && x < 100000)
{
}
Plus the error in the implementation of sum5() as pointed out by Osiris
.

Resources