I have a program I am writing that converts Octal to Decimal numbers. Most of it works.
(more code above this, assume all variables are properly declared).
for(i; i > 0; i--)
{
decimalNumber = (decimalNumber + (number['i'] * pow(8,power)));
power++;
}
The code correctly shifts over to the right to do other digits but it doesn't change the number it is working with. For example, entering 54 in octal results in an output of 36, 4*(8^0) + 4*(8^1) when it should be outputting 4*(8^0) + 5*(8^1), or 44.
'i' is a constant. You probably meant just i. Also, << 3.
As Ignacio pointed out, 'i' is a constant and will cause you to access the same out of bounds array element on each iteration of the loop. Since I assume you start with i equal to the number of digits in the array (you didn't show that code), you want to subtract 1 from it when you use it as an array index.
You're traversing the string in the wrong direction.
Or, better, change your logic:
5 -> 5*8^0
54 -> (5*8^0)*8 + 4
543 -> ((5*8^0)*8 + 4)*8 + 3
number[0] is 5
number[1] is 4
decimalNumber is 0
power is 0
i = 1 downto 0 do
decimalNumber = (decimalNumber + (number[i:1,0] * pow(8,power:0,1)));
power++;
do end
Related
Given a number, I want to modify the Nth digit of the number.
For example, given 1237645, I want to change the 4th digit from the right, which is 7 in this case, to say 5.
The only way in which I can think of is to do this
N = 1237645
fourthDigit = (N / 1000) % 10
N -= fourthDigit * 1000 // make fourth digit 0
N += 5 * 1000 // make fourth digit 5
But this is quite inefficient. Is there a better way to this? I cannot use array to represent N due to memory constraints.
You can do it in one arithmetic operation:
N = 1237645
fourthDigit = (N / 1000) % 10
N -= (fourthDigit-5) * 1000
provided fourthDigit >= 5, otherwise the last line becomes
N += (newDigit-fourthDigit)*1000
Is this embedded system programming?
If it is, then try storing numbers as binary-coded decimal (BCD), then convert to binary if you need to. It is probably easier to convert from BCD to binary than the other way around.
Also see: http://homepage.divms.uiowa.edu/~jones/bcd/bcd.html
BTW, right here in the room with me is a clock which keeps time in BCD. This way, it doesn't have to divide by 10 for display.
If c is the numerical value of an uppercase character (i.e. B is 66) and for the sake of argument, k is a key value of 2? I'm new to programming and don't understand how the modulo works in this. I know it takes the value of the remainder, but then wouldn't it simplify like this?
c = B = 66
k = 2
I imagine the result should be 'D'
(66 - 65 +2)%26 +65
(3)%26 +65
0 + 65
65 = 'A'
I must not understand the way % works.
Key Fact - The ASCII code of the letter"A" is 65.
Here is how your cypher works - the original expression in the question title.
Take the ASCII value of a letter, subtract the value of "A" from it giving you a 0 based number.
Add the key value to this number shifting it by k places.
Now divide the number you got above by 26, discard the quotient and use the remainder. This is the modulo operator %. This always keeps you numbers in the 0-25 range, since dividing by 26 will never a have a remainder great than 25.
Add 65 to it to convert it into an "encrypted" uppercase letter.
This allows the key to be ANY number and still keeps the "encrypted" output within the ASCII range of A-Z.
You are interpreting the % operator as division. In reality, it's modulo or forget-the-quotient-I want-the-remainder operator.
Example
0%2 is 0
1%2 is 1
2%2 is 0
3%2 is 1
And so on. Modulo is cyclic.
Modulus is not int division. Modulus gives you the remainder of a division, so 3 / 26 is 0 with a remainder of 3. Therefore, 3 % 26 is 3.
3 % 26 is 3, not 0. Modulus is the remainder. Think of modulus 12 on a clock. If it is ten o'clock, and you add 4 hours, 10 + 4 = 14. But on the clock, the hand now points to 2, not 14. No matter how many hours you add, the hand always points to a number from 1 to 12. This is how modulus works.
10 + 4 = 14
14 % 12 = 2 (14 divided by 12 is 1 with remainder 2)
10 + 100 = 110
110 % 12 = 4 (110 divided by 12 is remainder 4)
If it is 10 o'clock, and you wait 100 hours, the hand now points to 4.
(Using the remainder of a division, dividing by 12 always gives a number from 0 to 11, so think of 12 o'clock as 0 o'clock.)
((c - 65 + k) % 26) + 65) works, but is non portable and unnecessarily obfuscated.
65 is the ASCII code for 'A' the character constant representing the letter A. c - 65 or better c - 'A' evaluates to the distance of the uppercase letter stored in c from A, hence 1 for the letter B.
Adding k operates a shift in the alphabet, but can produce offsets greater than 25, hence the modulo operation to compute the remainder of the division by 26. (c - 65 + k) % 26 gives the offset if the encoded letter.
Adding 65 or more appropriately 'A' converts the offset back to an uppercase letter.
This expression makes the silent assumption that all uppercase letters are consecutive in the execution character set, which is true for ASCII, but not for older character sets such as EBCDIC.
Note also that the above expressions only work for positive values of k. If k is negative, the result of (c - 'a' + k) % 26 + 'a' may be negative too, hence k should be changed to a positive value first with this code:
k = k % 26;
if (k < 0)
k = k + 26;
Here is a more readable alternative:
char encode_letter(char c, int k) {
k = k % 26;
if (k < 0)
k = k + 26;
if (c >= 'A' && c <= 'Z')
return (c - 'A' + k) % 26 + 'A';
else
if (c >= 'a' && c <= 'a')
return (c - 'a' + k) % 26 + 'a';
else
return c;
}
I came across this C program:
int main() {
printf("Enter your address, (e.g. 51 Anzac Road) ");
gets(address);
number = 0;
i = 0;
while (address[i] != ' ') {
number = number * 10 + (address[i] - 48);
i++;
}
}
I understand number = number * 10 + (address[i] - 48); is to get the number from input, but can anybody explain to me how this works? How does that produce the number from the input?
C requires the digits 0 through 9 to be stored contiguously, in that order, in the execution character set. 48 is the ASCII value of '0', so, for instance:
'3' - 48 == 3
for any digit.
ASCII is not required for C, so better is:
'3' - '0'
because while 48 is right for ASCII, '0' is by definition right for any character set.
If address contains "456 ", then:
when i == 0 and number == 0, number * 10 + (address[0] - 48) equals 0 * 10 + 4, or 4.
when i == 1, number * 10 + (address[1] - 48) is 4 * 10 + 5, or 45.
when i == 2, number * 10 + (address[2] - 48) is 45 * 10 + 6, or 456
and you're done.
Never use gets(), it's dangerous, and isn't even part of C anymore.
In ASCII, the digit characters '0' through '9' occupy code points 48 through 57 (i hex, 0x30 through 0x39) so, to turn a digit character into a value, you just subtract 48.
As an aside, you should really subtract '0' since the standard doesn't guarantee ASCII, though it does guarantee that the digit characters are contiguous and ordered. C under z/OS, for example, uses EBCDIC which places the digits at code points 0xf0 through 0xf9.
The loop itself is a simple shift-and-add type, to create a number from multiple digit characters. Say you have the string "123", and number is initially zero.
You multiply number (zero) by ten to get zero then add digit character '1' (49) and subtract 48. This gives you one.
You then multiply number (one) by ten to get ten and add digit character '2' (50), again subtracting 48. This gives you twelve.
Finally, you multiply number (twelve) by ten to get a hundred and twenty then add digit character '3' (51) and subtract 48. This gives you a hundred and twenty three.
There are better ways to do this in the C standard library, atoi or the more robust strtol-type functions, all found in stdlib.h. The latter allow you to better detect if there was "rubbish" at the end of the number, for assistance with validation (atoi cannot tell the difference between 123 and 123xyzzy).
And, as yet another aside, you should avoid gets() like the plague. It, like the "naked" scanf("%s"), is not suitable for user input, and opens your code to buffer overflow problems. In fact, unlike scanf(), there is no safe way to use gets(), which is undoubtedly why it has been removed from C11, the latest standard. A more robust user input function can be found here.
There's also a large class of addresses for which that code will fail miserably, such as:
3/28 Tivoli Rd
57a Smith Street
Flat 2, 12 Xyzzy Lane
I am looking at the following piece of code:
void printd(int n)
{
if (n < 0) {
putchar('-');
n = -n;
}
if (n / 10)
printd(n / 10);
putchar(n % 10 + '0');
}
I understand the first if statement fine, but the second one has me confused on a couple of points.
By itself, since "n" is an integer, I understand that n/10 will shift the decimal point to the left once - effectively removing the last digit of the number; however, I am having a little trouble understanding how this can be a condition by itself without the result being equal to something. Why isn't the condition if ((n/10) >= 0) or something?
Also, why is the '0' passed into the putchar() call?
Can someone tell me how it would read if you were to read it aloud in English?
Thanks!
The n / 10 will evaluate to false if the result is 0, true otherwise. Essentially it's checking if n > 10 && n < -10 (the -10 doesn't come into play here due to the n = -n code)
The + '0' is for character offset, as characters '0'-'9' are not represented by numbers 0-9, but rather at an offset (48-57 with ascii).
Can someone tell me how it would read if you were to read it aloud in English?
If you're talking about the conditional, then I would say "if integer n divided by 10 is not zero"
n/10 will not shift the decimal number since n is an integer. The division will produce the result like this: if n = 25, then n/10 would be 2 (without any decimal points), similarly if n = 9, then n/10 would be 0 in which case if condition would not be satisfied.
Regarding the +'0', since n%10 produces an integer result and in putchar you are printing a char , you need to convert the integer to a char. This is done by adding the ascii value of 0 to the integer.
In C, there is no separate boolean type; an expression like a > b evaluates to zero if false, non-zero if true. Sometimes you can take advantage of this when testing for zero or non-zero in an int.
As for the '0', that just performs character arithmetic so that the right character is printed. The zero character has an ASCII encoding value which isn't zero, so the n value is used as an offset from that encoding to get the right numeric digit printed out.
I am trying to understand how to repeat loops using the mod operator.
If you have two strings, "abc" and "defgh", how can % be used to loop through abc, repeating it until the end of defgh is reached? Namely, what is the mod relationship of the length of abc and defgh?
I don't really understand this concept.
Simple.
std::string abc("abc");
std::string defgh("defgh");
for (size_t i = 0; i < defgh.length(); ++i)
{
printf("%c", abc[i % abc.length()]);
}
Think about what the Modulus operator is doing, it discretely divides the left hand side by the right hand side, and spits back the integer remainder.
Example:
0 % 3 == 0
1 % 3 == 1
2 % 3 == 2
3 % 3 == 0
4 % 3 == 1
In our case, the left hand side represents the i'th position in "defgh", the right hand represents the length of "abc", and the result the looping index inside "abc".
The typical usage of mod is for generating values inside a fixed range. In this case, you want values that are between 0 and strlen("abc")-1 so that you don't access a position outside "abc".
The general concept you need to keep in mind is that x % N will always return a value between 0 and N-1. In this particular case, we also take advantage of the fact that if you increase x by 1 x % N also increases by 1. See it?
Another important property of modulus that we use here is the fact that it "rolls over". As you increase x by 1, x % N increases by 1. When it hits N-1, the next value will be 0, and so on.
Look at #Daniel's code. It's C++ but the concept is language-agnostic