This question already has answers here:
Why is my power operator (^) not working?
(11 answers)
Closed 2 years ago.
I've been trying to find the length of a given number using this program, however I get the following error every time I run it:
check_length.c:16:26: runtime error: division by zero
#include <cs50.h>
#include <stdio.h>
void check_length(long);
int main(void)
{
long c = get_long("Enter Number: ");
check_length(c);
}
void check_length(long w)
{
for(int i=1;i<=16;i++)
{
int scale = w/((10)^i);
if (scale<10 && scale>0)
{
int length = i+1;
printf("%i\n",length);
}
}
}
The simple answer is that the operator ^ isn't doing what you expect. It seems you expect it to raise 10 to the power of i but ^ is actually the bitwise XOR operator.
So when i is 10, you do 10 XOR 10 which is zero. Therefore the division by zero.
You could take a look at the pow function instead but why make things that complicated?
Simply keep diving by 10 until you get zero and then return the number of divisions.
Something like this for non-negative values:
#include<stdio.h>
int check_length(unsigned long w)
{
int result = 0;
while (w > 0)
{
++result;
w = w/10;
}
return result;
}
int main()
{
printf("%d\n", check_length(0));
printf("%d\n", check_length(9));
printf("%d\n", check_length(10));
printf("%d\n", check_length(1234567890));
return 0;
}
Output:
0
1
2
10
Related
This question already has answers here:
Find the sum of digits of a number(in c)
(6 answers)
Closed 2 years ago.
Hello i need problem with this task in C language. If anyone had a similar problem it would help me.
The task is:
Write a program that loads the numbers a and b (a <b), then finds and prints the numbers from the segment of [a, b] and prints the sum of the digits of each number.
I wrote for three issues, for example:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n1,n2,sum=0,a,b,k,n3;
scanf("%d",&a);
scanf("%d",&b);
for(k=a;k<=b;k++)
{
n1=k%10;
n2=(k/10)%10;
n3=k/100;
sum=n1+n2+n3;
printf("%d\n",sum);
}
}
The problem arises when I enter a larger than three-digit number, how to make for any number, no matter if it is two-digit, three-digit, four-digit ...
Well the way you solve this issue depends on the exact requirements. Given that you only have ints here I would use the following though it is by no meand production code
int main() {
int a = whatever;
int b = whatever;
char* a_as_s = itoa(a);
char* b_as_s = itoa(b);
int sum_of_a = 0;
int sum_of_b = 0;
for(int i = 0; a_as_s[i]; i++)
sum_of_a += atoi(a_as_s[i]);
for(int i = 0; b_as_s[i]; i++)
sum_of_b += atoi(b_as_s[i]);
}
That should calculate the sum of digits for arbirary lengths - the rest of your code seems fine
You've already solved the iterating part so as people have suggested in the comments all you need now is a way to sum the digits of an arbitrary integer. I've modified your solution with my take on the problem. I'm pretty sure there is a more elegant/efficient way to do this, so I'd suggest you also check out the links people have provided in the comments. Anyhow here is my take:
#include <stdio.h>
int maxPowOf10(int num)
{
int divisor = 1;
for(;;)
{
if(num / divisor == 0)
{
break;
}
divisor *= 10;
}
return divisor / 10;
}
int sumOfDigits(int num)
{
int sum = 0;
for(int divisor = maxPowOf10(num); divisor >= 1; divisor /= 10)
{
int tmp = num / divisor;
sum += tmp;
num -= tmp * divisor;
}
return sum;
}
int main()
{
int n1,n2,sum=0,a,b,k,n3;
printf("Insert a: ");
scanf("%d",&a);
printf("Insert b: ");
scanf("%d",&b);
printf("Result\n");
for(k=a;k<=b;k++)
{
sum = sumOfDigits(k);
printf("number: %d sum of its digits: %d\n", k, sum);
}
return 0;
}
The approach is fairly straightforward. To find the sum of the digits, first you determine what is the largest power of 10 that still features in the number. Once that is found we can just divide by the largest power of 10 and add the result to sum. The trick is that, after that, we have to remove the part of the number that is described by the decimal place we are at. So we don't count it again. Then, you keep repeating the process for ever decreasing powers of 10. In the end you have the complete sum.
To illustrate this on 152 for example:
a) The largest power of 10 in 152 is 100.
b1) We divide 152 by 100 and get 1. We add 1 to sum. We also decrease the number to 52 (152 - 100)
b2) We divide 52 by 10 and get 5. We add 5 to sum. We decrease the number to 2 (52 - 50).
b3) We divide 2 by 1 and get 2. We add 2 to sum. We decrease the number to 0 (2 - 2).
Point a describes the method maxPowOf10
Point b describes the method sumOfDigits
This question already has answers here:
How do I determine the number of digits of an integer in C?
(20 answers)
Closed 2 years ago.
This is the code prompting the user for input
#include <stdio.h>
#include <cs50.h>
//prompt user for number
int main(void)
{
long number = get_long("Enter card number: ");
}
The below program will help you, but its bettor to give some effort
#include <stdio.h>
#include <cs50.h>
//prompt user for numb er
int main(void)
{
long number = get_long("Enter card number: ");
int count = 0;
do{
number = number / 10;
++count;
}while (number != 0) ;
printf("length of number = %d",count);
}
If you allow yourself to use floating point, the number of digits of a positive integer number A in base B is the logarithm of A in base B plus 1. Working in base 10 you could write:
long get_num_digits(long a)
{
long c;
if (a == 0) {
return 1;
}
if (a < 0) {
a = -a;
}
c = (long)log10((double)a);
++c;
return c;
}
You can do for instance:
#include <stdio.h>
#include <string.h>
void main()
{
long alpha = 352;
char s[256];
sprintf(s,"%ld",(alpha >= 0L) ? alpha : -alpha );
printf("long digits: %lu",strlen(s));
}
This version addresses an issue raised by Andrew Henle and is capable of dealing with a long with an arbitrary number of bits.
After the necessary precautions treating non-positive arguments, we calculate the log of the argument in base 2 and change the log base to base 10 by multiplying by lod_10(2).
The number of digits from the base 10 log of 2 must be chosen accordingly. The following version is good from 1 to 1000 bits longs, uses no floating point, one integer multiplication, one interger division and a maximum of N-1 shifts, where N is the number of bits of the argument.
/*
* Using 3 digits from log_10(2), we have enough precision to calculate the
* number of digits of a 1000 bit number.
*/
/* #define LOG_10_2 301029995663981198 */
#define LOG_10_2_NUMERATOR 301
#define LOG_10_2_DENOMINATOR 1000
long get_num_digits3(long a)
{
long c;
long i;
if (a == 0) {
return 1;
}
if (a < 0) {
a = -a;
}
/* i = log_2(a); */
i = 0;
while (a) {
a >>= 1;
++i;
}
/* c = log_10(a) + 1 */
c = (long)(LOG_10_2_NUMERATOR * i);
c /= LOG_10_2_DENOMINATOR;
++c;
return c;
}
So, first of all I'm a total beginner in C, we're studying it at University on the course 'Structured Programming'.
Now, the last few lectures about 'Recursive functions' have been a pain for me as a beginner. Could anyone of you be kind enough to explain me this:
So I have this little script, a recursive function that takes a decimal number and converts it to a binary one:
#include <stdio.h>
void binary(int num)
{
if (num == 0) return;
binary(num / 2);
printf("%d", num % 2);
}
int main()
{
int n;
scanf("%d", &n);
binary(n);
return 0;
}
Now I was wondering, how does this function work? I know the logic behind it and whats its supposed to do, but I don't know how it does IT. The printf in the bottom is especially throwing me off, for example if the printf function is before the recursive call, for the input decimal 10 it prints out (0101) but if its under it it prints out the correct binary number (1010)?
Any kind of help is greatly appreciated, kind regards.
The reversal is done using the call stack of the functions. By that I mean that the way the functions are called, this guarantess that the MSB will be printed first then the next one and so on.
void binary(int num)
{
if (num == 0) return;
binary(num / 2); // Wait, I will print but you first print the MSB's.
printf("%d", num % 2); // Now I print the last digit.
}
Downward motion moves the calls.
{binary(12)
{binary(6)
{binary(3)
{binary(1)
binary(0) -- returns
Now we print 1
}
print 1
}
prints 0
}
prints 0
}
If one wants to print recursively the bits of a char with leading zeros,
he may use following code:
#include <stdio.h>
void print_bit_iter(char x, int n)
{
int bit = (x & (1 << n - 1)) != 0;
printf("%d", bit);
if(n != 0)
print_bit_iter(x, n - 1);
}
int main()
{
print_bit_iter('U', 8);
}
This will have
01010101
as the output.
I have to write a program that takes in two positive integers, start and end, where (1 < start < end). Then the program would look within this range [start, end] and count the number of powers of 3.
So, for example, if start is 2 and end is 10, the output would be 2. (as 3 and 9 are powers of 3).
Below is my code:
#include <stdio.h>
#include <math.h>
int main(void) {
int start, end, i, count = 0;
printf("Enter start and end: ");
scanf("%d %d", &start, &end);
for (i = start; i <= end; i++) {
if ((log(i) / log(3)) == floor((log(i) / log(3)))) {
printf("%d\n", i);
count++;
}
}
printf("Answer = %d\n", count);
return 0;
}
But, when I tried to run one of the test cases [3, 1000], the output is 5, when it should be 6.
3
9
27
81
729
Answer = 5
The number 243 is missing. Is there something wrong with my code?
The problem is you are using exact comparison of floating point numbers. Specifically, here:
if ((log(i)/log(3)) == floor((log(i)/log(3))))
Since log() and floor() return double, you're comparing without any tolerance two values which cannot be compared that way.
How should I do floating point comparison?
Your immediate problem has to do with the imprecision of floating point numbers, something that is generally well documented on the net, including various methods useful in fixing that problem.
However, I'm not actually going to bother referring you to them because the use of floating point is totally unnecessary here. There's a much more efficient way of doing this that involves only integers.
Rather than going through numbers in your range looking for powers of three using floating point operations, you would be better off going through powers of three (using just integer multiplication) looking for numbers in your range.
In pseudo-code, that would go something like:
powerOfThree = 1
while powerOfThree <= endRange:
if powerOfThree >= startRange:
print powerOfThree
powerOfThree = powerOfThree * 3
You could even make it more efficient by selecting a more suitable starting value for powerOfThree but, since there are only 40-odd powers of three in a 64 bit number, that's probably a waste of time.
When converting from pseudo-code to the more concrete C, you unfortunately come across the limitations of the datatypes in that language, specifically the fact that multiplication may result in overflow.
There are various ways you can avoid this this such as detecting that it's about to happen and exiting the loop early.
Given below is the function that you need, one which handles this issue, along with some test code which can be used for validating it.
#include <stdio.h>
#include <limits.h>
// I hate typing :-)
typedef unsigned long ULONG;
typedef unsigned int UINT;
static UINT countPowersOfThreeBetween (ULONG low, ULONG high) {
// Catch invalid params, just exit with zero.
if (low > high) return 0;
// Go through all powers of three.
ULONG powerOfThree = 1;
UINT count = 0;
do {
// If within your range, count it.
if ((powerOfThree >= low) && (powerOfThree <= high)) {
count++;
// printf ("DEBUG: got %lu\n", powerOfThree);
}
// Early exit if about to overflow.
if (ULONG_MAX / powerOfThree < 3) break;
// Advance to next power and continue if within range.
powerOfThree *= 3;
} while (powerOfThree <= high);
// Notify caller of count.
return count;
}
// Test function to make test suite easier.
static void testRange (ULONG low, ULONG high) {
UINT count = countPowersOfThreeBetween (low, high);
printf ("In range %lu..%lu, found %u occurrences\n", low, high, count);
}
// Test suite, add whatever you need.
int main (void) {
testRange (1000, 10);
testRange (0, 0);
testRange (9, 9);
testRange (3, 1000);
testRange (0, ULONG_MAX);
testRange (ULONG_MAX, ULONG_MAX);
return 0;
}
As you will see from the output, this gives the correct counts for various ranges:
In range 1000..10, found 0 occurrences
In range 0..0, found 0 occurrences
In range 9..9, found 1 occurrences
In range 3..1000, found 6 occurrences
In range 0..18446744073709551615, found 41 occurrences
In range 18446744073709551615..18446744073709551615, found 0 occurrences
And, if you uncomment the printf line in countPowersOfThreeBetween(), you'll also see the actual values detected.
Before choosing floating point types in the future, I strongly recommend you read this article entitled "What every computer scientist should know about floating-point arithmetic", by David Goldberg. It explains your problem(s) nicely, much better than I could have.
You don't actually need floating point (or negative integer) types here, so they should be avoided. Form your powers by multiplication, rather than addition:
#include <assert.h>
#include <limits.h>
#include <stdio.h>
int main(void){
unsigned int start, end, i, count = 0;
printf("Enter start and end: ");
int x = scanf("%u %u", &start, &end);
assert(x == 2); // XXX: INSERT PROPER ERROR HANDLING!
// find the first power greater than or equal to start
for (i = 1; i < start && UINT_MAX / 3 >= i; i *= 3);
// ... then count each one less than or equal to end
while (i <= end && UINT_MAX / 3 >= i) {
printf("%u\n", i);
i *= 3;
count++;
}
printf("Answer = %u\n", count);
}
Your problem is round-off error while float calculating in computer, the result of log(243)/log(3) is not exactly log3(243), where computer store approximate value of it. eg, in my 32bit computer, it is 4.99999999999999911182.
However, you have two ways to solve it,
use integer calculation instead of float.
simple mathematical transformation.
number of powers of 3 in [start, end] is equivalent to floor(log3(end)-log3(start))+1, wrote in c is
printf("answer:%d\n", (int)((log(1000)-log(3))/log(3))+1);
complete code:
#include <stdio.h>
#include <math.h>
int pow3(int n) {
int ret = 1;
while(n--) {
ret *= 3;
}
return ret;
}
int main() {
int a, start, end, answer;
scanf("%d%d", &start, &end);
a = (int)(log(start+0.5)/log(3));
//printf("%d,%d,%d\n", a, pow3(a), start);
if(start == end) answer = (start == pow3(a));
else answer = (int)((log(end+0.5)-log(start))/log(3))+1;
printf("answer = %d\n", answer);
}
Result:
Input[0]: 2 10
Output[0]: 2
Input[1]: 1 3
Output[1]: 2
Input[2]: 3 1000
Output[2]:6
Your program fails because of floating point precision issues.
Use integer arithmetics instead:
#include <limits.h>
#include <stdio.h>
int main(void) {
unsigned int start, end, i, count;
printf("Enter start and end: ");
if (scanf("%u %u", &start, &end) == 2) {
for (i = 1, count = 0; i <= end && i <= UINT_MAX / 3; i *= 3) {
if (i >= start) {
printf("%u\n", i);
count++;
}
}
printf("Answer = %u\n", count);
}
return 0;
}
A direct solution with floating point arithmetics is possible too:
#include <math.h>
#include <stdio.h>
int main(void) {
unsigned int start, end, count = 0;
printf("Enter start and end: ");
if (scanf("%u %u", &start, &end) == 2) {
if (end > 0 && end >= start) {
int start3 = (start <= 1) ? 0 : (int)(log(start - 0.5) / log(3));
int end3 = (int)(log(end + 0.5) / log(3));
count = end3 - start3;
}
printf("Answer = %u\n", count);
}
return 0;
}
I am coming to SO as a last resort. Been trying to debug this code for the past 2 hours. If the question is suited to some other SE site, please do tell me before downvoting.
Here it goes:
#include <stdio.h>
#include<math.h>
int reverse(int n) {
int count = 0, r, i;
int k = (int)log(n * 1.0);
for(i = k; i >= 0; i--)
{
r = (n % 10);
n = (n / 10);
count = count + (r * pow(10, k));
}
return count;
}
int main(void) {
int t;
scanf("%d", &t);
while(t--)
{
int m, n, res;
scanf("%d %d", &m, &n);
res = reverse(m) + reverse(n);
printf("%d", reverse(res));
}
return 0;
}
My objective is to get 2 numbers as input, reverse them, add the reversed numbers and then reverse the resultant as well.I have to do this for 't' test cases.
The problem: http://www.spoj.com/problems/ADDREV/
Any questions, if the code is unclear, please ask me in the comments.
Thank you.
EDIT:
The program gets compiled successfully.
I am getting a vague output everytime.
suppose the 2 numbers as input are 24 and 1, I get an output of 699998.
If I try 21 and 1, I get 399998.
Okay, if you had properly debugged your code you would have notices strange values of k. This is because you use log which
Computes the natural (base e) logarithm of arg.
(took from linked reference, emphasis mine).
So as you are trying to obtain the 'length' of the number you should use log10 or a convertion (look at wiki about change of base for logarithms) like this: log(x)/log(10) which equal to log10(x)
And now let's look here: pow(10, k) <-- you always compute 10^k but you need 10^i, so it should be pow(10, i) instead.
Edit 1: Thanks to #DavidBowling for pointing out a bug with negative numbers.
I don't know how exactly you have to deal with negative numbers but here's one of possible solutions:
before computing k:
bool isNegative = n < 0;
n = abs(n);
Now your n is positive due to abs() returning absolute value. Go on with the same way.
After for loop let's see if n was negative and change count accordingly:
if (isNegative)
{
count = -count;
}
return count;
Note: Using this solution we reverse the number itself and leave the sign as it is.
It looks like Yuri already found your problem, but might I suggest a shorter version of your program? It avoids using stuff like log which might be desirable.
#include <stdio.h>
int rev (int n) {
int r = 0;
do {
r *= 10;
r += n % 10;
} while (n /= 10);
return r;
}
int main (void) {
int i,a,b;
scanf("%d",&i);
while (i--) {
scanf("%d %d",&a,&b);
printf("%d\n",rev(rev(a) + rev(b)));
}
return 0;
}
Hopefully you can find something useful to borrow! It seems to work okay for negative numbers too.
Under the hood you get char string, reverse it to numeric, than reverse it to char. Since is more comfortable work with chars than let's char:
char * reverse (char *s,size_t len) //carefull it does it in place
{
if (!len) return s;
char swp, *end=s+len-1;
while(s<end)
{
swp =*s;
*s++=*end;
*end--=swp;
}
return s;
}
void get_num(char *curs)
{
char c;
while((c=getchar())!='\n')
*curs++=c;
*curs=0;
}
int main()
{
double a,b,res;
char sa[20],sb[20],sres[20],*curs;
get_num( sa);
get_num(sb);
reverse(sa,strlen(sa));
reverse(sb,strlen(sb));
sscanf(sa,"%f",&a);
sscanf(sb,"%f",&b);
res=a+b;
sprintf(sres,"%f",res);
reverse(sres);
printf(sres);
}