Value of C define changes unexpectedly - c

I have a lot of #define's in my code. Now a weird problem has crept up.
I have this:
#define _ImmSign 010100
(I'm trying to simulate a binary number)
Obviously, I expect the number to become 10100. But when I use the number it has changed into 4160.
What is happening here? And how do I stop it?
ADDITIONAL
Okay, so this is due to the language interpreting this as an octal. Is there some smart way however to force the language to interpret the numbers as integers? If a leading 0 defines octal, and 0x defines hexadecimal now that I think of it...

Integer literals starting with a 0 are interpreted as octal, not decimal, in the same way that integer literals starting with 0x are interpreted as hexadecimal.
Remove the leading zero and you should be good to go.
Note also that identifiers beginning with an underscore followed by a capital letter or another underscore are reserved for the implementation, so you shouldn't define them in your code.

Prefixing an integer with 0 makes it an octal number instead of decimal, and 010100 in octal is 4160 in decimal.

There is no binary number syntax in C, at least without some compiler extension. What you see is 010100 interpreted as an octal (base 8) number: it is done when a numeric literal begins with 0.

010100 is treated as octal by C because of the leading 0. Octal 10100 is 4160.

Check this out it has some macros for using binary numbers in C
http://www.velocityreviews.com/forums/t318127-using-binary-numbers-in-c.html
There is another thread that has this also
Can I use a binary literal in C or C++?

If you are willing to write non-portable code and use gcc, you can use the binary constants extension:
#define _ImmSign 0b010100

Octal :-)
You may find these macros helpful to represent binary numbers with decimal or octal numbers in the form of 1's and 0's. They do handle leading zeros, but unfortunately you have to pick the correct macro name depending on whether you have a leading zero or not. Not perfect, but hopefully helpful.

Related

Is there a way to convert octal input to decimal/binary output without using math.h library and pow?

Beginner programmer here.
Is there a way to input octal values and expect decimal or binary outputs without the use of functions or the math.h library? I have an idea of using a loop to achieve this but I haven't the faintest clue of how it should look like and what loop to use. I appreciate your help. Thank you.
stdio.h functions are allowed
math.h functions are not allowed
everyone. I have found a solution. I used decimal to octal code and switched values.
while loop for decimal to octal:
while(input){
rem1=input%8;
input=input/8;
ans1=ans1+(rem1*place_value);
place_value1=place_value1*10;
}
while loop for octal to decimal:
while(input){
rem1=input%10;
input=input/10;
ans1=ans1+(rem1*place_value);
place_value1=place_value1*8;
}
For octal to binary, simply take the answer from octal-decimal and use decimal to binary. Thank you everyone for helping.

Printf format specifiers

I've been trying to cobble together the format of printf into a sort of linear format. Is the following a correct understanding of the possible printf formats?
% <justification: [-]?> <sign: [ +]?> <alternate: [#]?>
<padding: [0? num]?> <precision: [.num]?> <modifier: [h|hh|l|ll|L|z|t|j]?>
<format: [c|d(i)|e(E)|f|o|p|x(X)|u|s|g(G)]>
Is the order and meanings correct in the above? A couple examples being:
printf(" %-10.3s %-+20ld", "Hello!", 14L);
Is the following a correct understanding of the possible printf formats?
"Generally" yes, but for example you "can't" do %jg or like %0#p.
There is also %n.
Both "precision" and "padding" may be asterisks, like %*s or %.*s (but you could have defined num as ([0-9]+|\*)...).
Also . is optionally followed by a number. So it's more like <precision: [. num? ]> - if only . is specified, precision is taken as zero.
Is the order
The order of - +#0 is irrelevant and you can repeat them, so you can %-+020d and %+0-+++000----20d with same meaning (and 0 is ignored when used with -, so also there are corner cases).
meanings correct in the above?
There is no explanation in the above. - is not "justification" (taken literally, a word?), it's a flag that makes the output be left justified within the field. Also meaning depends on context - "precision" for floats maybe can be understood as the number of digits after comma, but "precision of a string" sounds strange. But generally, yes.
Your specification is too restrictive:
the flags +, -, #, 0 and space can appear in any order, but some combinations are meaning less, such as %+s.
width and precision can be specified as *
a and A were introduced to produce hexadecimal floating point representations
F is available and different from f for NaNs and infinities.
%% and %n should be recognised too.
Here is a regular expression to match all valid printf conversion specifications, but that will not detect invalid combinations:
%[ +-#0]*{[*]|[1-9][0-9]*}?(.{[*]|[0-9]*}?)?{h|hh|l|ll|L|z|t|j}?[%naAcdieEfFopxXusgG]
You might refine it to reject any flags for %% and restrict other cases too, but it will become quite complicated to express as a regex.

Is subtracting a char by '0' to convert to int bad practice?

I'm expecting a single digit integer input, and have error handling in place already if this is not the case. Are the any potential unforeseen consequences by simply subtracting the input character by '0' to "convert" it into an integer?
I'm not looking for opinions on readability or what's more commonly used (although they wouldn't hurt as an extension to the answer), but simply whether or not it's a reliable form of conversion. If I ask the user to input an integer between 0 and 9, is there any scenario in which there can be input that input = input-'0' should handle, but doesn't?
This is safe and guaranteed by the C language. In the current version, C11, the relevant text is 5.2.1 Character sets, ¶3:
In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.
As for whether it's "bad practice", that's a matter of opinion, but I would say no. It's both idiomatic (commonly used and understood by C programmers) and lacks any alternative that's not confusing and inefficient. For example nobody reading C would want to see this written as a switch statement with 10 cases or by setting up a dummy one-character string to pass to atoi.
The order of characters are encoding/system-dependent, so one must not rely on a particular order in general. For the sequence of digits 0..9 in any system, however, it is guaranteed that it starts with 0 and continues to 9 without any intermediate characters. So input = input - '0' is perfect as long as you guarantee that input contains a digit (e.g. by using isdigit).

Print a number in base 4

Lately I had a task that included printing base-4 representation of a number. Since I didn't find a function to do it for me, I implemented it (which is not so hard of course), but I wonder, is there a way to do it using format placeholders?
I'm not asking how to implement such function, but if such function / format placeholder already exists?
There is no standard C or C++ function, but you may be able to use itoa
The closest you could get to doing it with printf is using snprintf to convert it to hex, then a lookup table to convert hex digits to pairs of base-4 digits. :-)
No, not in the Standard C library.
I think that printf can handle only decimal, hexadecimal and octal values.
So i think no.

Why are hexadecimal numbers prefixed with 0x?

Why are hexadecimal numbers prefixed as 0x?
I understand the usage of the prefix but I don't understand the significance of why 0x was chosen.
Short story: The 0 tells the parser it's dealing with a constant (and not an identifier/reserved word). Something is still needed to specify the number base: the x is an arbitrary choice.
Long story: In the 60's, the prevalent programming number systems were decimal and octal — mainframes had 12, 24 or 36 bits per byte, which is nicely divisible by 3 = log2(8).
The BCPL language used the syntax 8 1234 for octal numbers. When Ken Thompson created B from BCPL, he used the 0 prefix instead. This is great because
an integer constant now always consists of a single token,
the parser can still tell right away it's got a constant,
the parser can immediately tell the base (0 is the same in both bases),
it's mathematically sane (00005 == 05), and
no precious special characters are needed (as in #123).
When C was created from B, the need for hexadecimal numbers arose (the PDP-11 had 16-bit words) and all of the points above were still valid. Since octals were still needed for other machines, 0x was arbitrarily chosen (00 was probably ruled out as awkward).
C# is a descendant of C, so it inherits the syntax.
Note: I don't know the correct answer, but the below is just my personal speculation!
As has been mentioned a 0 before a number means it's octal:
04524 // octal, leading 0
Imagine needing to come up with a system to denote hexadecimal numbers, and note we're working in a C style environment. How about ending with h like assembly? Unfortunately you can't - it would allow you to make tokens which are valid identifiers (eg. you could name a variable the same thing) which would make for some nasty ambiguities.
8000h // hex
FF00h // oops - valid identifier! Hex or a variable or type named FF00h?
You can't lead with a character for the same reason:
xFF00 // also valid identifier
Using a hash was probably thrown out because it conflicts with the preprocessor:
#define ...
#FF00 // invalid preprocessor token?
In the end, for whatever reason, they decided to put an x after a leading 0 to denote hexadecimal. It is unambiguous since it still starts with a number character so can't be a valid identifier, and is probably based off the octal convention of a leading 0.
0xFF00 // definitely not an identifier!
It's a prefix to indicate the number is in hexadecimal rather than in some other base. The programming language uses it to tell compiler.
Example:
0x6400 translates to 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600.
When compiler reads 0x6400, It understands the number is hexadecimal with the help of 0x term. Usually we can understand by (6400)16 or (6400)8 or whatever ..
For binary it would be:
0b00000001
Good day!
The preceding 0 is used to indicate a number in base 2, 8, or 16.
In my opinion, 0x was chosen to indicate hex because 'x' sounds like hex.
Just my opinion, but I think it makes sense.
Good Day!
I don't know the historical reasons behind 0x as a prefix to denote hexadecimal numbers - as it certainly could have taken many forms. This particular prefix style is from the early days of computer science.
As we are used to decimal numbers there is usually no need to indicate the base/radix. However, for programming purposes we often need to distinguish the bases from binary (base-2), octal (base-8), decimal (base-10) and hexadecimal (base-16) - as the most commonly used number bases.
At this point in time it is a convention used to denote the base of a number. I've written the number 29 in all of the above bases with their prefixes:
0b11101: Binary
0o35: Octal, denoted by an o
0d29: Decimal, this is unusual because we assume numbers without a prefix are decimal
0x1D: Hexadecimal
Basically, an alphabet we most commonly associate with a base (e.g. b for binary) is combined with 0 to easily distinguish a number's base.
This is especially helpful because smaller numbers can confusingly appear the same in all the bases: 0b1, 0o1, 0d1, 0x1.
If you were using a rich text editor though, you could alternatively use subscript to denote bases: 12, 18, 110, 116

Resources