Reversing a 5 digit number gives negative number - c

This is my program for reversing a number.But when I take 5 digits as input, sometimes the answer is correct and positive and sometimes it's negative.
#include<dos.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int main()
{
clrscr();
int a,b,c;
b=0;
printf("Enter the no");
scanf("%d",&a);
c=a;
while(a>0)
{
b=(b*10)+(a%10);
a=a/10;
}
printf("\noriginal no %d",c);
printf("\nreversed no is %d",b);
getch();
return 0;
}
If input: 12111
output: 11121
input: 22333
output: -32214
The limit of integer is from -32768 to 32767, then why is the answer negative?
I tried using long but I got my reversed number as 0.

It looks like this is a 16-bit DOS program? So your int is only 16 bits/2 bytes, and your program is overflowing it.
You could try detecting when this condition will happen, and/or use unsigned to avoid negative numbers or a long instead of int to store bigger values (though this program will still output incorrect answers if you overflow).
What's the overall aim? - Can you just doing it by reversing a string instead?

As Bathsheba mentioned, sizeof(int) is apparently 2, and given the headers you're using, the platform is MS-DOS, which means your int only has 16 bits of information available. Because the first bit is the sign bit, that leaves you with 15 bits and 2^15 is 32768, meaning your range is -32767..+32767. What you want is an unsigned int and %u for scanf and printf. That will allow you to use 0..65535.
Need to be able to handle all 5-digit numbers? Switch to long instead (it won't matter if you make it signed or unsigned other than using %ld or %lu for signed or unsigned respectively), and you will have -2147483648..+2147483647 (signed) or 0..4294967295 (unsigned), which will give you more than enough range for a 5-digit number.
If you have problems with using long and the format is correct for scanf and printf, the problem is in your logic and not your reading of numbers at least.

If the limit is 32767, then reversing 22333 would yield 33322, which is larger than the limit!!!
If you want to use long instead of int, then you should also use "%ld" instead of "%d".

Related

C Program to Print an Integer (Entered by the User) Wrong Output Coming When The number is BIG [duplicate]

This question already has answers here:
Why are the array elements changed after sort,C
(2 answers)
Closed 4 years ago.
Here is my code for the program.
#include <stdio.h>
int main() {
int number;
printf("Enter an integer: ");
scanf("%d", &number);
printf("You entered: %d", number);
return 0;
}
If I enter an integer: 12345678912345678
Result is Showing: 1578423886
Why is this happening ?
The problem is that on the system you're running on, int is not large enough to store integers as large as you're trying to enter (the limit is architecture-specific, and can be checked via INT_MAX). If you define your variable as a long long instead, it will be able to hold larger values (long long is 64 bits on most common architectures), and so:
#include <stdio.h>
int main() {
long long number;
printf("Enter an integer: ");
scanf("%lld", &number);
printf("You entered: %lld", number);
return 0;
}
outputs:
Enter an integer: 12345678912345678
You entered: 12345678912345678
That happens because data types on any programming language have limits, so you cannot simply put any number into an integer data type. Probably for your test the limit is 2.147.483.647 for integer data type, if you want to receive a bigger number you will have to switch to long or maybe unsigned long, it all depends of your needs, and when it comes to handle really really big numbers probably you will need to read it as string and then parse it to a special structure or class than can handle that really big number.
This is happening because On a system if the value won't fit in an int, then the result of the conversion is implementation-defined. (Or, starting in C99, it can raise an implementation-defined signal, but I don't know of any compilers that actually do that.) What typically happens is that the high-order bits are discarded, but you shouldn't depend on that. (The rules are different for unsigned types; the result of converting a signed or unsigned integer to an unsigned type is well defined.)
Because of this discarding you get result like mention in comment 12345678912345678 is a 54-bit number. In hex it's 0x2bdc545e14d64e. Interestingly enough 1578423886 is 0x5e14d64e(lower bits are same and higher are discarded)

Factorial program in C is wrong after 20 [duplicate]

This question already has answers here:
Cannot calculate factorials bigger than 20! ! How to do so?
(7 answers)
Closed 6 years ago.
It works up until 20 but if 21 is entered it returns 1419745... when 21 factorial is actually 51090942171709440000. I'm assuming that this is because of the unsigned long maxing out but where does this wrong number (141...) come from and how can I allow the program to work out the factorial of larger numbers?
#include <stdio.h>
unsigned long fact(unsigned long input);
int main()
{
int input;
printf("Enter an integer to find the factorial of: ");
scanf(" %d", &input);
printf("The Factorial of %d = %lu\n" , input, fact(input));
return 0;
}
unsigned long fact(unsigned long input)
{
if (input == 0)
return 1;
else
return input * fact(input - 1);
}
This answers only to half of your question (why it works this way).
The result you get is 21! mod 2^64. This is because you are using a 64-bit system and 21! is greater than the greatest number that can be stored as unsigned integer on 64 bits.
All factorials you compute for values greater than or equal to 21 are wrong; they cannot be represented on 64-bit integers because they are longer than that.
You can try to use unsigned long long as the type of the values returned by function fact() (and change into the printf() format string %lu with %llu); it could help but it depends on some factors. It doesn't help on my architecture, for example.
You can find out if it can help you by checking the value returned by sizeof(unsigned long long). If if is 8 then you are out of luck. 20 is the largest number for what you can compute factorial on that system.
If your purpose is to compute factorials then you have to use a library that knows how to handle large numbers. However, if you need factorials for other computations (for example, for combinations) then you can try to avoid generating large numbers and find a way to match each multiplication with a division. This way the magnitude of the numbers you use is between the limits of 64-bit integers and you can go further than 21.
Or you can use double instead of integers and you are again back in business but with loss of precision. Large floating point numbers store correctly the magnitude of the number and its first digits. The last digits are lost.
I didn't program very much in C/C++ recently, I cannot recommend you a library that can help you do computations with large numbers :-(
The number comes from overflow. Unsigned arithmetic is done modulo (max value of that type), so a little maths should explain why you get the result you do.
The result of signed integer overflow is undefined so you could have got anything if you'd been using signed integers (though the chances are it'd have been exactly the same on a lot of systems)

Parsing a number with more than 10 digits in C

I'm trying to calculate UPC codes using C as a language, but I'm now having a problem with the precision. I tried int, float, long long, etc.
Here's the code:
#include <stdio.h>
int main(void)
{
float upc;
printf("Enter UPC:\n");
scanf ("%d", &upc);
printf("upc = %f ", upc);
}
the results are :
Enter UPC code:
123456789012
upc = 123456790528.000000 d= 1
Process returned 30 (0x1E) execution time : 6.672 s
Press any key to continue.
How can I show the number as is? It's only 12 digits.
I'm using CodeBlocks, is there an IDE that can handle this better?
Note: please don't tell me to just use char! I want to make some calculations later.
Universal product codes are not subject to integer arithmetic operations, so it doesn't entirely make sense to represent them using int. Each digit is assigned a particular meaning, so a string makes more sense.
If you really just want a band-aid, uint64_t from <stdint.h> will always be able to hold a 12-digit number. Do not use a floating-point type, though, as they are not designed to hold exact integers, but rather to approximate real numbers.
The correct way to use uint64_t with printf and scanf is with the fixed-width format specifiers from <inttypes.h>:
scanf ( "%" SCNd64, &upc);
printf("upc = %" PRId64 "\n", upc);
A float can typically store just 6-7 decimal digits. A 32-bit int can store 9 digits (10 if the leading digits is 3 or less). To store a 12-digit integer, you need to use either a long long (up to 18 digits) or perhaps a double (up to 15-16 digits), though a double is less desirable.
Hence:
#include <stdio.h>
int main(void)
{
long long upc;
printf("Enter UPC:\n");
scanf ("%lld", &upc);
printf("upc = %lld\n", upc);
return(0);
}
Actually can you be more clear of what you want as your output? I suggest you one modification in to use long long int instead of float.

C MVS-Input with more than 10 digits

Recently I tried to write a code that searches for a certain number in a given n.
The code worked perfectly but when I tried to insert n with more than 10 digits it got realy bad.
Apparently it had nothing to do with the code, I just couldn't insert more than 10 digits.
I must be missing something...
For example this simple code
#include <stdio.h>
int main()
{
long int n;
scanf("%ld", &n);
printf("%ld", n);
return 0;
}
If I feed it 1111111111 it would print the same thing becuase its less than 11 digits
If I try to feed it 11111111111 it would give me something like -1773790777
Why is this happening to me? what am I doing wrong...
I'm guessing you are on a 32-bit machine, which means that the long int is only 32 bits, which means it can hold values between minus 2 billion to plus 2 billion. When you try to enter much more than that, the value wraps over.
You should start using a 64-bit value like long long int if your compiler supports it.
Overflow of signed integers is undefined behaviour. I think your long int is of 4 bytes which is causing overflow when you enter a bigger number than it can hold.

greater integer width

i m trying to enter a five digit number greater than 32767 and i used "unsigned" while declaring int number, and when i m trying to print the same number it prints some arbitary negative number,
results get overflowed......
pls help me out
Without seeing your code, I am guessing you are using %d or %i in the printf statement. Use %u instead.
Print unsigned values using "%u" instead of "%d".
Until you show some of the code, I can't be sure of anything.
But AFAIK you shouldn't be able to print out a negative number if you're printing out an uint – even if it overflows, the integer will always hold a positive number, as far as C is concerned.
So there's something else wrong.
Use correct format specifier.
%d for int
%u for unsigned int.
Using incorrect format specifier in printf() may cause Undefined Behavior.
For example, the following code invokes Undefined Behavior(UB).
#include<stdio.h>
int main(void)
{
unsigned int z=Some_value; /*Some_value is an unsigned int */
printf("%d",z);
/*UB as format specifier for unsigned int is incorrect,it should be %u not %d*/
}
I guess int is 16bit on your machine/compiler.
Though I don't know what your platform is, I guess that long would solve your problem (it is 32bit or more on all platforms I know). Print it with %ld instead of %d.
Don't get tempted to use unsigned and %u, because they will just give you numbers up to 65536, and I guess that you want more.

Resources