ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Just another question while I'm here: Have I finally understood properly now? (octal and hexadecimals that is)
I believe so. One minor thing which I think might be a typo, or unintentional error. You wrote up to 7 for Octal. Correct. You wrote up to 16 for Hexadecimal. No, up to 15.
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Thanks again jpollard.
I did look up how to convert from hexadecimal to decimal, but beyond dividing the what I assume is the number itself by the base (16), it didn't really make a lot of sense to me. I'm sure you're right in what you're saying, but I just don't fully understand the formula for doing it yet - you wouldn't be able to give a quick example would you? Just so I can see exactly what you're talking about.
I sorta understand what you're saying about compression, but not a 100% sure. I always thought that if say (and this is clearly not a real example) for example if "ab" meant say just "1" in whatever it is, then that would "compress" "ab" into "1", and then the program would know that "1" actually means "ab" in that fake example. I don't really know how else to explain my thinking there, so sorry if that doesn't make sense.
I'm not really sure exactly what you mean by the last paragraphs in your post above, other than the obvious. I did look up about "16-bit", "bit", etc in Wikipedia, while most of it made at least some sense, I'm not 100% clear on what you're saying above (apart from the obvious once again).
According to Google, 1 bit = 0.125 byte, but beyond that I'm not 100% clear on it.
Thanks RT!
I still don't know why I wrote "16", but yes, I meant "15". So yes, that was indeed unintentional. But thanks again for your post.
I said before to use your computer's calculator to show you this stuff, instead of trying to always figure it out.
Get the answer first and then try on paper to explain it. This way you know when you have an error.
It looks like jpollard has given you an example.
My recommendation is that you convert in both ways, and make sure you can get it correctly.
Use the calculator to get the values of a number in both hex and decimal. And not a big number, use any value below decimal 200.
Stay away from very large numbers, I can explain later. But seeing you have difficulty still converting numbers, then my primary concern is that you learn how to do that.
I recommend you try the value 149. That is 0x95 in hexadecimal. I used my calculator for you.
1. Use the method jpollard gave you to convert it to hex. Currently there is a typo in their post, but I feel it should not be incomprehensible for you.
2. When you have it in hex, then convert it to decimal:
a. Multiply the second digit, the '9', by 16.
b. Add the first digit, the '5', to that result.
c. If you didn't get 149, there's something wrong.
Show your work.
Don't try a bunch of other numbers, or even one other number.
Show us you can get this correct, or indicate where you are stuck.
I did look up how to convert from hexadecimal to decimal, but beyond dividing the what I assume is the number itself by the base (16), it didn't really make a lot of sense to me. I'm sure you're right in what you're saying, but I just don't fully understand the formula for doing it yet - you wouldn't be able to give a quick example would you? Just so I can see exactly what you're talking about.
The remainder of the division is what is used to pick the symbol for the digit. For hex, the list of digits is "0123456789ABCDEF".
So if the division resulted in 4, count the four places, and use the next digit - so skipping 0,1,2,3 (four digits), and the next is the one to use (4). If the remainder is 11, skip the first 11, and the next is the digit so "0123456789A" get skipped, a B is the digit.
This is also why indexing is based on 0, rather than 1 (as discussed above) as it is easier to do. A remainder of for would then access the base of the list of symbols. In 0 based indexing, a remainder of 0 is the first element in the list... which is "0", making it easier to do for things up to a remainder of 9. A remainder of 11 is over that, so now the list is extended. A remainder of 10 would skip the first 10 symbols (0123456789),and use the "A".
A remainder of 11 would then use "B".
Quote:
I sorta understand what you're saying about compression, but not a 100% sure. I always thought that if say (and this is clearly not a real example) for example if "ab" meant say just "1" in whatever it is, then that would "compress" "ab" into "1", and then the program would know that "1" actually means "ab" in that fake example. I don't really know how else to explain my thinking there, so sorry if that doesn't make sense.
Lets take the string ABC for radix 50 notation. the A maps to a value of 1. B maps to a value of 2, C maps to a value of 3. So the sequence of letters is now a sequence of numbers 1, 2, 3
To convert to radix 50.
1. the results starts at 0 (all blanks)
2. Since this is the first known digit, it the result * 50 + the value. (result * 50 is zero since the result STARTS at 0). Adding the value the result is now 1.
2. repeat for the next digit: the result * 50 + the value (result * 50 is now 50). adding the value makes the result 52.
3. repeat for the next digit: the result * 50 + the value (result * 50 is now 52*50 -> 2600) adding the value make the result 2600+3 or 2603.
A 16 bit value is two 8 bit bytes. Now the standard table for the latin alphabet (which has far more characters than a radix 50 notation, including upper case/lower case/numbers/special characters/control characters...) and GENERALLY needs up to 256 values to represent the symbols...
This is also an old standard (ASCII) which actually only uses 127 symbols - which leaves one bit sort of unused. I say "sort of" because the bit has been used for error detection in communication devices (it is a "parity bit" - this is rarely used now as devices became more reliable, but it used to be used to detect errors. If the original 8 bit value was even, then the "parity bit" would be set to 1, if the value was odd then it would be set to a 1. This form was called "odd parity", and allowed the detection of errors by checking the number of bits that were a 1. If the count always came up odd - then no error occurred. If it ever came up even, then the byte was miscommunicated. The same if you invert the meaning of parity (even parity). The only difference is that now the value must allways be an even value. This "parity" bit is not used that way anymore as other methods of error detection (and even correction) are now standard.
This means that one byte (8 bits) can hold in general one character. So 16 bits (two bytes) can only hold two characters.
16 bits can hold no more than 65535 different values... so our radix 50 notation for ABC, is only 2603, which EASILY fits in two bytes - thus storing three symbols in two bytes instead of only storing two symbols in two bytes.
This is a compression...
It only works if the radix is large enough to hold all the symbols you need. Using an entire byte is a radix 256 notation... But is usually ignored as a single byte is also a unit of storage.
Quote:
I'm not really sure exactly what you mean by the last paragraphs in your post above, other than the obvious. I did look up about "16-bit", "bit", etc in Wikipedia, while most of it made at least some sense, I'm not 100% clear on what you're saying above (apart from the obvious once again).
According to Google, 1 bit = 0.125 byte, but beyond that I'm not 100% clear on it.
A byte is 8 bits, so one bit would be 1/8 of a byte (0.125 byte). But otherwise is pretty useless in application. A bit only only has one of two values (0 or a 1). It is the aggregation of 8 bits grouped together, that allows for 2^8 different values to be stored as a collection of bits (0 to 255 in base 10, where 0 is 00000000 and 255 is 11111111).
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Quote:
Originally Posted by rtmistler
...
2. When you have it in hex, then convert it to decimal:
a. Multiply the second digit, the '9', by 16.
b. Add the first digit, the '5', to that result.
c. If you didn't get 149, there's something wrong.
...
Thanks RT.
I used KCalc to do the above and I got 149.
Thanks jpollard.
I divided the example RT gave me (0x95) by 16 (both just the "9" and also the "95") and got "0.5625" for "9 / 16" and "5.9375" for "95 / 16". So does that mean I need to divide the "95" and not just "9" by "16"? Because I got the "9" for the remainder?
I *think* I understand the rest of what you said - but I'll probably have to read it a few times before it sinks in.
Last edited by jsbjsb001; 01-23-2019 at 12:06 AM.
Reason: typo
I divided the example RT gave me (0x95) by 16 (both just the "9" and also the "95") and got "0.5625" for "9 / 16" and "5.9375" for "95 / 16". So does that mean I need to divide the "95" and not just "9" by "16"? Because I got the "9" for the remainder?
Not exactly. You don't use fractional notation. The reason it is not used is that this is an imprecise representation. There are certain fractions that cannot be represented exactly, so you can get the wrong result from calculators sometimes. This is one of the reasons calculators have a display base (programmer calculators that is). Selecting hex just switches the display to using a simpler conversion for base 2 (binary) or base 16 (hex). It is simpler because the numbers are ALREADY in base 2 internally.
0x95 is already in hex notation (as specified by the 0x), so dividing 0x95 by 16 you get 0x9, with 0x5 for a remainder. Now 0x95 is 149 base 10. dividing 149 by 16 you a quotient of 9 with a remainder of 5. thus the rightmost hex value is 5.
9 is less that 16 so the only remainder you get by dividing by 16 is 9. So the hex value of the base 10 number 149 is 0x95.
Quote:
I *think* I understand the rest of what you said - but I'll probably have to read it a few times before it sinks in.
One of the reasons people use hex for some constants is that they can more easily convert to binary - both bases are powers of 2 (binary is base 2, hex is base 16, which is 2*2*2*2). This is useful in programming as it allows for storing boolean flags in an aggregate - as an unsigned number. an 8 bit unsigned number can hold 8 flags.... much more compact than using 8 bytes... This is used in communications because sending a byte with flags is faster than sending 8 bytes. It is one of the things that makes raw packet interpretation tricky - it is full of data compression to try and make communication faster.
In device control situations, it means the device has fewer electronics (saving money) to handle the data.
You don't understand yet, and you made a mistake which I unexpected.
You've already been informed what was up with that mistake, however I'll re-iterate.
0x95 is hexadecimal. That is what the '0x' indicates.
Also: 95H is hexadecimal. That is also what the 'H' indicates.
These are both notations meaning hexadecimal. Neither is wrong.
Converting FROM a hexadecimal number TO decimal means that the number gets bigger. Provided it is larger than 0xF to start with.
Converting TO a hexadecimal number FROM decimal means that the number gets smaller. Again, provided it is larger than 15 (decimal) to start with.
THIS ONLY APPLIES TO TWO-DIGIT HEXADECIMAL NUMBERS AND I DO NOT WISH YOU TO EXPAND WITH MORE DIGITS FOR NOW
To start simple:
- With a two digit hexadecimal number, the right-most digit is the value of 'ones'.
- You've seen that those values can be: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, and F.
- Those correspond to decimal values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, and 15.
- The left-most digit is the value of 'sixteens'.
- Same values, however they represent the first power of sixteen.
- In other words, you multiply that left-most digit by 16 to get the decimal equivalent.
Hence:
- 0x95
- Left-most digit is '9', which would be 9 x 16 = 144
- Right-most digit is '5', which would be 5 x 1 = 5
- Add those two results: 144 + 5 = 149. Correct Result
The other way:
- 149
- Divide that by 16, which would be 149 / 16 = 9 and that is 9 in hex, which represents 'nine values of sixteen'.
- The remainder for that is 5. No further calculations because the number is no longer greater than 15.
- Therefore you write it as 0x95 which means 'nine values of sixteen, plus five values of ones'
Another example:
- Let's say the number was in decimal: 161
Convert that to hex:
- Divide it by 16, which would be 161 / 16 = 10, the value of ten represented in hex is 0xA
- The remainder for that is 1.
- Therefore the result is 0xA1
Going from hex back to decimal:
- 0xA1
- Left-most digit is 'A', which would be 10 x 16 = 160
- Right-most digit is '1', which would be 1 x 1 = 1
- Add those two results: 160 + 1 = 161. Correct Result.
I still will explain larger hexadecimal numbers and why I've told you to stay lower valued.
I'm bearing in mind that you are still making errors, so I wish to stay fundamental.
Here are some exercises:
REMEMBER TO FIRST CHECK THESE WITH A CALCULATOR
1. Convert 0xB2 to decimal
2. Convert 0x55 to decimal
3. Convert 183 to hexadecimal
4. Convert 99 to hexadecimal
5. Convert 64 to hexadecimal
Show your work. Please indicate where you are stuck.
Minor additional note. I do see jpollard's points, and they are all correct. Understanding hexadecimal numbers and 'intuitively' understanding what they represent, as well a being able to visualize what they mean in binary is VERY IMPORTANT to C programming.
I assume it's just the "4" that I include for the remainder, if the remainder is more than just one digit/number? I also assume if there is no remainder, that it's just the first digit?
The conversions from hex to decimal are incorrect.
For starters, you have always have a way to check this:
Quote:
Originally Posted by rtmistler
REMEMBER TO FIRST CHECK THESE WITH A CALCULATOR
Earlier in this thread I mentioned that the calculator application on any system will show values in hex, and decimal and that you can check what a value is to verify what you've done.
Therefore you can always ask yourself: "Was what I did correct? Did it make sense? Can I check it?"
Quote:
Originally Posted by jsbjsb001
I assume it's just the "4" that I include for the remainder, if the remainder is more than just one digit/number? I also assume if there is no remainder, that it's just the first digit?
Correct, there is no remainder, however the '4' represents the number of "sixteens" in the number. This is because you divided it.
16 x 4 = 64.
64 / 16 = 4, no remainder.
The hexadecimal result is 0x40
Which means "4 x 16", and nothing additional.
Yes I gave you that one intentionally, and will continue to do so.
Quote:
Originally Posted by jsbjsb001
1. 11 x 16 = 176 + 2 = 178 Correct
2. 5 x 16 = 80 + 5 = 85 Correct
5. 64 / 16 = 4 = 0x4 Nearly Correct. I mentioned it above.
3. 183 / 16 = 11.4375 = 0xB4
183 / 16 = 11, with a remainder 16 x 11 = 176 183 - 176 = 7 (this is how you extract the remainder)
11 decimal in hexadecimal is 0xB The resultant hexadecimal number to represent 183 is 0xB7
4. 99 / 16 = 6.1875 = 0x61 99 / 16 = 6 16 x 6 = 96 99 - 96 = 3 (this is how you extract the remainder)
The resultant hexadecimal number to represent 99 is 0x63
How about one more round? Yes, please use the calculator to tell you what the result should be, and then perform your calculations. If you make a mistake, then please do admit it, however also please do work to resolve it using the information you've been provided. I'm saying you're absolutely allowed to verify the answers therefore getting them 100% correct. I'm also saying that if you fail to be capable of duplicating them without the calculator, that you still have a misunderstanding. Therefore it will be helpful to clear it up.
1. Convert 0xFF to decimal
2. Convert 0x0A to decimal
3. Convert 200 to hexadecimal
4. Convert 128 to hexadecimal
5. Convert 127 to hexadecimal
6. Convert 96 to hexadecimal
7. Convert 30 to hexadecimal
Advanced topic:
- 1030 decimal is 0x406
- Please verify that on your calculator
- See if you can determine how those numbers can be converted.
- At least see if you can figure out what the 4 means, or convert 0x400 using the calculator.
This is why calculators for programmers have a modulus operation. Sometimes a botton with a % on it, other times a "mod" label.
Do it long hand: 16)183...
16 can be subtracted from 18 only once - so the quotent digit above the 8 is 1. Since this is the 10s place that is 1*10.
The subtraction gives you a REMAINDER of 2 (because it is 18 * 10, this becomes 2*10 for 20..
Now bring down the 3 (the ones place) and add it to the 20 for 23.
16 can be subtracted from 23 only once. so the quotient above the 3 is a 1. Adding to the 1*10 before makes the quotient 11. The subtraction of 16 from 23 gives a remainder of 7. THIS is the last digit of the hex number.
16 can not be subtracted from 11 so 11 is the remainder. In the sequence of symbols for hex this corresponds to a "B". So the final hex number B7.
The problem with using a calculator with fractions is that the calculator can round the fraction... and that will give you the wrong result.
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Thanks again RT,
I think it was getting the remainder that I didn't understand before, in that: I was getting confused between the remainder and the fraction (as jpollard pointed out above). I wrote out the decimal number with their hex equivalents in a text file, like, 1 = 1 (hex), 2 = 2 (hex), and so on and so forth, so I think I can see what you're saying. But I would prefer if you continued explaining how to do the calculations, to get to the hex value of the given decimal number, if you would. I know for exercise 6 that it's "1E" that's the answer, but I couldn't figure it out with doing the conversion, like I did below with the rest of them. I kept getting the wrong answer when I tried with doing the conversion, so I'm honestly not sure how to do that one.
I'm not sure how I would get the hex value for "1030", while I can see the answer is "0x406", I'm at a loss as to how to find that out, other than using the little program astrogeek wrote me (or like I was doing; write them out in my text file). I tried to get KCalc to show me the hex values, and while it does have a "Mod" button, I don't know how to work it.
1. 15 x 16 = 240 + 15 = 255
2. 0 x 16 = 0 + 10 = 10
3. 200 / 16 = 12.5 16 x 12 = 192 - 200 = 8 = 0xC8
4. 128 / 16 = 8 = 0x80
5. 127 / 16 = 7.9375 16 x 7 = 112 - 127 = 15 = 0x7F
6. 96 / 16 = 6 = 0x60
7. 30 / 16 = 1.875 16 x 8 = 128 - 30 = 98 = 0x1? (I know it's "1E", but I cannot work that out with the calculations)
I think it was getting the remainder that I didn't understand before, in that: I was getting confused between the remainder and the fraction (as jpollard pointed out above). I wrote out the decimal number with their hex equivalents in a text file, like, 1 = 1 (hex), 2 = 2 (hex), and so on and so forth, so I think I can see what you're saying. But I would prefer if you continued explaining how to do the calculations, to get to the hex value of the given decimal number, if you would. I know for exercise 6 that it's "1E" that's the answer, but I couldn't figure it out with doing the conversion, like I did below with the rest of them. I kept getting the wrong answer when I tried with doing the conversion, so I'm honestly not sure how to do that one.
I'm not sure how I would get the hex value for "1030", while I can see the answer is "0x406", I'm at a loss as to how to find that out, other than using the little program astrogeek wrote me (or like I was doing; write them out in my text file). I tried to get KCalc to show me the hex values, and while it does have a "Mod" button, I don't know how to work it.
1. 15 x 16 = 240 + 15 = 255
2. 0 x 16 = 0 + 10 = 10
3. 200 / 16 = 12.5 16 x 12 = 192 - 200 = 8 = 0xC8
4. 128 / 16 = 8 = 0x80
5. 127 / 16 = 7.9375 16 x 7 = 112 - 127 = 15 = 0x7F
6. 96 / 16 = 6 = 0x60
7. 30 / 16 = 1.875 16 x 8 = 128 - 30 = 98 = 0x1? (I know it's "1E", but I cannot work that out with the calculations)
1030 base 10 convert to hex.
Code:
STEP 1. get the least significant remainder...
64 (the final quotient)
-----
16)1030
96 (6*16)
---
70 (subtracting 96 from 103 -> 7, then bringing down the 0, for 70)
64 (4 * 16)
--
6 (subtracting 64 from 70 -> 6 first remainder from dividing 1030 by 16,
giving the quotient 64, with a remainder of 6)
STEP 2. Get the next least significant remainder by dividing the quotient from the first step by 16
4 (quotient of 64 devided by 16)
---
16)64 (quotient from previous division)
64 (16*4)
==
0 (subtracting 64 from 64 giving the second remainder by dividing 64 by 16,
giving the quotient 4, with a reminder of 0
STEP 3. Since the quotient is not yet zero, divide the quotient from the previous step by 16
0 (quotient of dividing 4 by 16
--
16)4
0 (16 * 0)
-
4 (subtracting 0 from 4 gives the remainder from dividing 4 by 16
giving a quotient of 0 and a remainder of 4).
done: all the quotients are now known.
Now, lets look at the remainders from the last value (which is the most significant digit) to the first remainder (the least significant). That list is 4, 0, 6.
Translate each of the remainders by the HEX table:
Code:
base 10 base 16
hex
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 A
11 B
12 C
13 D
14 E
15 F
So the translation of 4, 0, 6 becomes 406 hex. and the conversion of 1030 is 0x406.
The point of the table is that anything can be used for the table, it is just a convenience that 0123456789ABCDEF is used. These are just symbols for a value, and adding the ABCDEF makes a convenient extension to the base 10 digits 0123456789 with the least amount of learning new symbols...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Thanks again jpollard for your help. It was only because you explained on the right-hand side of the code box, that I could follow how you got to the final result.
So just so I understand the steps involved in converting from decimal (base 10) to hexadecimal (base 16);
We first divide the decimal number (the whole decimal number) by "16", then we multiply the first number by "16" in the result of the previous division, then we subtract the result of the previous multiplication of the first number(s) from the original decimal value, minus the zero on the end, which we "bring down" to put on the end of the result of the previous subtraction, and then subtract the result of the previous subtraction (with the zero we "bought down" on the end of that result) from the previous multiplication, to get the first hex number/symbol, then repeat that process until we know the whole hex value for the given decimal number?
Because this is very confusing. Is there an easier way of working it out ?
I think you are combining steps making it appear more complex than it really is.
Each step is a division of the quotient of the previous step.
The remainder of each division specifies the digit of the number in the base. The very first division is naturally the least significant digit, as this is the result of remainder * base^0. The 0 is because you just started.
The second division provides the remainder for the next digit: the remainder * base^1
This is the same thing you get if you were converting a base 10 number to a base 10 number (though that is called an identity, you can do exactly the same steps, you get the same number you started with).
taking 123 as the number, dividing by 10 gives you a quotient of 12, with a remainder of 3 (which is 3 * 10^0)
taking 12 as the number, dividing by 10 gives you a quotient of 1, with a remainder of 2 (which is 2 * 10^1).
taking 1 as the number, dividing by 10 gives you a quotient of 0, with a remainder of 1 (which is 1 * 10^2).
Adding the (3* 10^0) + (2 * 10^1) + (1 * 10^2) and you get 3 + 20 + 100 => 123.
Each step is relatively straight forward (even if long division is a pain), but it shows the answer.
This is why many calculators include the modulo operation - it will give you the remainder of a division (though they don't show the quotient at the same time... you can get that by using the division operation).
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
I appreciate your help jpollard, and I'm sure your right in what you're saying, but it's just getting more and more beyond me at this point. I have no idea why I need to do any of the steps you guys talk about other than it converts it from decimal to hex. I'm not trying to be funny or anything, but it's just beyond me.
While it's probably a waste of time asking the following question given the above, I'll ask it anyway;
In the C pdf, it says the following for one of the exercises at the end of the "Program Looping" chapter;
Quote:
2. Write a program to generate and display a table of n and n2, for integer values of n
ranging from 1 to 10. Be certain to print appropriate column headings.
The last part is obvious and was fairly easy, but does the "n2" (with the small "2") mean an "exponent", and therefore n x n ?
I've posted my code below, but if the question above does mean "n2" as in an "exponent", then I don't think my code below does that, and I have no idea how to get it to do that. So I'm not even sure what the question is even asking me to do.
Code:
#include <stdio.h>
int main(void)
{
int number, plusnumber = 0;
printf("Table of Triangular Numbers\n");
printf("number Sum of 2 to number\n");
printf("------ ------------------\n");
for( number = 1; number <= 10; ++number) {
plusnumber += number;
printf("%2i %2i\n", number, plusnumber);
}
return 0;
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.