Reputation: 81
I am an intermediate Python programmer, but I am trying to learn C. It is an extremely frustrating experience so far.
Why does this simple code...
#include <stdio.h>
#include <string.h>
char name[15] = "George Lopez"; /* string representing your name */
char birthday[6] = "01-30-92"; /* string representing your bday */
int phone_number; /* declair int representing phone number */
int main() {
phone_number = 2222223333; /* int representing your phone number */
printf("You said your name was: %s\n", name);
printf("And your birthday is %s?\n", birthday);
printf("And, so I can call you, your number is %d\n", phone_number);
return(0); /* exit program normally */
}
produce this output when the phone number is 2222223333:
You said your name was: George Lopez
And your birthday is 01-30-92?
And, so I can call you, your number is -2072743963
This output when the phone number is 9992223333:
error: 4_1_myinfo.c:16:3: warning: overflow in implicit constant conversion [-Woverflow]
phonenumber = 9992223333;
And this output when the phone number is 1112223333:
You said your name was: George Lopez
And your birthday is 01-30-92?
And, so I can call you, your number is 1112223333
I suspect this has to do with how C deals with integers. Perhaps, ints in C have a smaller maximum length than ints in python and this is resulting in wanky output?
Upvotes: 1
Views: 124
Reputation: 10857
The range of a signed 32-bit integer is [-2147483648, 2147483647]. You try to represent your phone number as a signed integer.
a. When phone num is 1112223333, it's less than the max 2147483647, so you get theright output.
b. 2222223333 is greater than the max 2147483647, but can still be represented as a 32-bit number, you get the 2's complement number which is -2072743963
c. 9992223333 cannot be represented by a 32-bit number, i.e. it's even bigger than (2^32 - 1), that's why you such error.
Upvotes: 0
Reputation: 9062
To understand why this is happening, you need to understand how the numbers are represented in memory. I will try to give you a glimpse of the basic way they work and some further references in case you are interested. As the computer understands just 0 and 1, base 2 is the obvious choice. But there is a problem with representing negative numbers. There are some representations, like the sign-magnitude representation (basically, have a bit that represents the sign - if it is set, the number is negative), that are very simple. The problem is that such representations have 2 ways of representing 0: +0 and -0. So, a clever representation, called two's complement is used. For a binary number abcd (where a, b, c, d represent its bits), the base 10 value is a*2^3+b*2^2+c*2^1+d*2^0. If this number was a 2's complement 4-bit representation, its base 10 value would be -a*2^3+b*2^2+c*2^1+d*2^0. So, in two's complement, the first bit has a negative weight. In a 4-bit two's complement representation, if you have 0111 (decimal 7) and you try to add 1, you will get 1000, which is -8. This is called an overflow. Overflow arises just when adding numbers with the same sign and obtaining a result of different sign (adding 2 positive numbers results a negative number or adding 2 negative numbers results a positive number).
In your program, something similar happens. The only difference is that int has 32 bits, not 4.
Further references: http://en.wikipedia.org/wiki/Binary_number http://en.wikipedia.org/wiki/Signed_number_representations
Upvotes: 0
Reputation: 19333
You have a couple of major issues here.
First, when using C-strings, avoid defining the size of the buffer if you can, like so:
char name[] = "George Lopez"; /* string representing your name */
char birthday[] = "01-30-92"; /* string representing your bday */
If you MUST pre-defined the maximum string length, use a common limit, like so:
#define MAX_STR_LEN 256
char name[MAX_STR_LEN] = "George Lopez"; /* string representing your name */
char birthday[MAX_STR_LEN] = "01-30-92"; /* string representing your bday */
If you don't plan on modifying them in the future, make them const
like so:
const char* name = "George Lopez"; /* string representing your name */
const char* birthday = "01-30-92"; /* string representing your bday */
In your case, you defined a character array that could only hold 6 characters, but tried to stuff 9 characters in it "01-30-92", plus the trailing \0
character included automatically. Big mistake.
The second major issue is that you are attempting to fit an integer literal into a data type which can not hold it. In C, the maximum signed 32-bit value, 2,147,483,647
, is defined as INT_MAX
in <limits.h>
. You should make your code like so:
long long int phone_number = 2222222222L;
Notice the trailing numeric literal suffix, L
? That's to allow your code to compile, and using a long long int
is necessary to create a variable that can actually store the value itself.
Finally, you should consider using strings to hold the phone number. You aren't doing any algebraic/mathematical manipulations on it, so there's no need to use an integral data type to represent it.
Code Listing (Modified)
#include <stdio.h>
#include <string.h>
char name[] = "George Lopez"; /* string representing your name */
char birthday[] = "01-30-92"; /* string representing your bday */
long long int phone_number; /* declair int representing phone number */
int main() {
phone_number = 2222223333L; /* int representing your phone number */
printf("You said your name was: %s\n", name);
printf("And your birthday is %s?\n", birthday);
printf("And, so I can call you, your number is %lld\n", phone_number);
return(0); /* exit program normally */
}
Sample Output
You said your name was: George Lopez
And your birthday is 01-30-92?
And, so I can call you, your number is 2222223333
Upvotes: 3
Reputation: 48
I think the better way to deal with phone numbers is to consider them as a string. You'll need a string type for "formatting" your outputs and also to verify that a phone number follow a certain "regular expression" when considering user inputs.
Upvotes: 1
Reputation: 62472
In C all datatypes have a fixed size. Typically an int
is a 32 bit value (but it doesn't have to be) so it will have a maximum value of 2,147,483,647.
Your value, 9,992,223,333 exceeds this value, which it why you are getting a warning. You need to use a bigger datatype like a 64 bit number. This will typically either be a long long
if you're on Windows, or a long
if you're on Linux.
Upvotes: 0