How to work with Base 8 (Octal) numbers? - c++

In C++, an octal number is defined by preceeding it with a 0, example:
01 = 1
010 = 8
014 = 12
So I was experimenting how working with Base 8 in c++ works, and tried adding to it with a loop, like so:
int base8Number = 00;
for (int i = 01; i < 011; i+=01)
{
base8Number += i;
cout << base8Number << '\n';
}
And apparently, C++ doesn't like working with octal numbers, the output I got is as follows:
1
3
6
10
15
21
28
36
The most obvious reason I know it's not working in Base 8, is the 28 output as a result, since the 8 number isn't used in Base 8.
So, my question: Can you work with Base 8 in c++, or is it just meant to be used as a constant, and if you can work with Base 8 in c++, how do you do it?

So first, let's remember that when we print numbers the way you're doing, they will be shown in decimal.
Now, let's rewrite your code without octal:
int base10Number = 0;
for (int i = 1; i < 9; i+=1)
{
base10Number += i;
cout << base10Number << '\n';
}
So let's now look at what your code is actually doing:
cout << 1 << "\n"; // 1
cout << 1 + 2 << "\n"; // 3
cout << 1 + 2 + 3 << "\n"; // 6
cout << 1 + 2 + 3 + 4 << "\n"; // 10
....
Which is what you're seeing. So no, there is no problem with how octal works in c++.
If you'd like you can use std::oct to tell std::cout to use octal printing. For example:
int main() {
std::cout << std::oct << 25 << "\n"; // Outputs: 31
}

Remember that "base" is a property of number representation, not the number itself. If you've got enough pegs to put one on each finger, then that is the same number of pegs regardless of whether you write 10, 012 0xA, or anything else.
Your code computes the numbers which would be shown in base 10 as 1, 3, 6, 10, 15, etc. You output them in base 10. To output them in base 8 use:
std::cout << std::oct << base8Number << std::endl;

There are a couple of things going on here.
Intrinsically, your computer operates in binary (base 2). When you do something like int foo = 10;, you are expressing the number 10 in decimal form because it's convenient for you to read it that way, but in the end the computer will still store it using binary, e.g. 1010.
If you were to use an octal literal (e.g. 012), then as far as the computer's concerned that's still just a 1010 binary constant - the only thing that's changed is its representation in the source code.
Finally, the last thing to realise is that the computer will by default output integers in base 10, because that's what's easy for people to read. It's still outputting the number 1010, just using the decimal representation of it.
Given all of the above, your code is entirely equivalent to doing the following, which you can verify for yourself produces the same output without using any octal:
int num = 0;
for (int i = 1; i < 9; i += 1) // Constants the same, just changed from octal representation to decimal.
{
num += i;
cout << num << '\n'; // Outputs in decimal, as with original program.
}
To get what you expect, try using the oct modifier:
int base8Number = 00;
for (int i = 01; i < 011; i+=01)
{
base8Number += i;
cout << oct << base8Number << '\n';
// ^--Here. Explicitly requests octal output.
}
This then explicitly requests that the computer output the values using octal.

Related

Why does my code give me different answers when I initialize a variable compared to when I add a simple value like 0? [duplicate]

This question already has answers here:
What happens when I print an uninitialized variable in C++? [duplicate]
(4 answers)
Closed 2 years ago.
Below you have two different codes. The difference between the two is simply for the variable sum, sum was initialized compared to giving sum the value 0 sum =0;
#include <iostream>
using namespace std;
int main(){
//This code will display first ten numbers and get the sum of it
cout << "The natural numbers are: " << endl;
for(int i=1; i<=10; i++)
{
cout << i << " ";
}
cout << endl;
// variable was initialized
int sum;
cout << "The sum of first 10 natural numbers: ";
for(int i=1; i<=10; i++)
{
sum = sum +i;
}
cout << sum;
cout << endl;
}
This Code outputs:
The natural numbers are:
1 2 3 4 5 6 7 8 9 10
The sum of first 10 natural numbers: 32821
Program ended with exit code: 0
#include <iostream>
using namespace std;
int main(){
//This code will display first ten numbers and get the sum of it
cout << "The natural numbers are: " << endl;
for(int i=1; i<=10; i++)
{
cout << i << " ";
}
cout << endl;
// here I gave the value 1... this time it worked
int sum =0;
cout << "The sum of first 10 natural numbers: ";
for(int i=1; i<=10; i++)
{
sum = sum +i;
}
cout << sum;
cout << endl;
}
This Code outputs:
The natural numbers are:
1 2 3 4 5 6 7 8 9 10
The sum of first 10 natural numbers: 55
Program ended with exit code: 0
Why does the code do this? Can someone please explain to me why they gave me two different sums?
If you do not initialize sum it has an indeterminate value and there's no way you can tell what operations on it will do. Reading an uninitialized variable is undefined behaviour and doing so renders your entire program invalid.
Btw; you seem to be confused about what initialization is. int sum; does not initialize sum, it just declares it - it does not give it an initial value and you may not read it or use it in computations until you have assigned it a known value. int sum = 0; does initialize sum - that is, it gives it an initial value and you can now validly read it and use it in computations.
Actually in the first set of code the compiler took a random value of variable sum. In your case I think the compiler took value of of sum as 32766. This value 32766 is "garbage value".
So see in second case you gave sum a initial value hence compiler knows that user has given a value. So accordingly it will perform your given operation. Inside the loop sum will start from 0 and keep performing the given operation until it exit the loop.
The operation for this Case2 codes is given below :
sum = sum + i; //(here value of "i" increase by 1 with iteration of the given loop)
/* 1 = 0 + 1
3 = 1 + 2
6 = 3 + 3
10 = 6 + 4
15 = 10 + 5
21 = 15 + 6
28 = 21 + 7
36 = 28 + 8
45 = 36 + 9
55 = 45 + 10
As you can see the value of "sum" after the loop is 55
*/
But in first case you didn't give sum initial value, so compiler don't know whether the value of sum is 0, 6, 15, 7 or 10. So, compiler took a random value for it, in your case it is 32766. Inside the loop it start from 32766 and continue its given operation.
The operation for the Case1 codes see below :-
sum = sum + i; //(like previous case here too value of "i" increase by 1 with iteration of the given loop)
/* 32767 = 32766 + 1
32769 = 32767 + 2
32772 = 32769 + 3
32776 = 32772 + 4
32781 = 32776 + 5
32787 = 32781 + 6
32794 = 32787 + 7
32802 = 32794 + 8
32811 = 32802 + 9
32821 = 32811 + 10
Here you can see the value of "sum" after the operation is 32821
*/
Okay! summing up everything, your logic and code looks fine to me but in first case the value of sum was allotted by compiler randomly, so here everything went wrong for the first case.
Activate the compiler flag -Wuninitialized.
In the first program, the sum is kept uninitialized and contained garbage value. Thus, you get the error. OTOH, in the second program, the value of sum is initialized to 0, which is exactly a zero and thus, the count did successful.
When you write int sum; in c++, a space in the memory is reserved for this variable, because it's not only a declaration, but also a definition. As sum is not set to any value yet, then, in this case, it gets any crazy value stored in it's space of memory that was already stored there before. Hope it helped :) Here are some useful links about this:
link1;
link2

Write a program that prompts the user to input an integer and then outputs both the individual digits of the number and the sum of the digits

For Example: Input: 982
Outputs: 9 8 2
Your Total sum is: 19
I see people using input_number % 10 in a loop and then input_number / 10 but I still do not get it. If i did 982 % 10 I would get 2 and then they add it to the sum which is 0 + 2 = 2 and how would that get 19???? and then the input number which is 982/10 is equal to 9.82 how does lead me to my solution of 19?? I am just super confused can someone please explain it to me and try to work out the problem and make it into a simple solution. I appreciate it and try to use the basic stuff like including namespace std and then not using arrays just loops and simple math equations thank you.
int n,sum=0;
cin>>n;
while(n!=0)
{
sum=sum+(n%10);
n=n/10;
}
/*
Since your n is an integer it will drop the value after decimal.
Therefore, 982 will run as
Iteration 1 n=982
sum=2
n=982/10=98
Iteration 2
sum=2+(98)%10 = 10
n=98/10= 9
Finaly in iteration 3
n=9/10=0 hence loop will terminate and sum be 19*/
You should input the number as a characters, that you convert into the digits and then individual numbers, that are easy to add or print or whatever. Avoid complicated math when you can totally live without it.
std::string str;
std::cin >> str;
int sum = 0;
for( int i=0; i<str.length(); i++) {
if( isdigit(str[i]) ) {
std::cout << str[i] << " ";
sum += int(str[i] - '0') // convert a char to int
}
}
std::cout << std::endl;
std::cout << "Total sum: " << sum << std::endl;
or something like that. Haven't programmed in C++ for a while, there might be minor mistakes in the code, but you get the general idea.

Function behave differently with similar input (C++)

I am trying to work with the modbus protocol and right now i am calculating the LRC of the messages. I made a function which worked with no issue whatever i was putting into and then i noticed that id did not worked with one input and i can't find a logical explanation on why this don't work.
The function is :
void LRCstring(std::string example)
{
std::stringstream ss;
std::string hex =example.substr(1, example.length()-5);
std::vector<unsigned char> hexCh;
unsigned int buffer;
int offset = 0;
while (offset < hex.length()) {
ss.clear();
ss << std::hex << hex.substr(offset, 2);
ss >> buffer;
hexCh.push_back(static_cast<unsigned char>(buffer));
offset += 2;
}
unsigned char LRC=0x00;
int i;
for (i=0;i<hexCh.size();i++)
{
LRC=LRC+hexCh[i];
}
LRC = 0xFF-LRC; // 1 complement
LRC = LRC+1; // 2 complement
//std::string s = std::to_string(LRC);
//int deci = atoi(s.c_str());
int deci = LRC;
int reste=deci % 16;
std::string temp;
int partiehexa=(deci-reste)/16;
std::string temp2;
std::cout << "deci : " << deci << std::endl;
std::cout << "reste : " << reste << std::endl;
std::cout << "partiehexa : " << partiehexa << std::endl;
std::stringstream ss2;
ss2 << reste;
ss2 >> temp;
ss2 << partiehexa;
ss2 >> temp2;
if (partiehexa<10) {LRCascii+=temp2;}
if (partiehexa==10) {LRCascii+='A';}
if (partiehexa==11) {LRCascii+='B';}
if (partiehexa==12) {LRCascii+='C';}
if (partiehexa==13) {LRCascii+='D';}
if (partiehexa==14) {LRCascii+='E';}
if (partiehexa==15) {LRCascii+='F';}
if (reste<10) {LRCascii+=temp;}
if (reste==10) {LRCascii+='A';}
if (reste==11) {LRCascii+='B';}
if (reste==12) {LRCascii+='C';}
if (reste==13) {LRCascii+='D';}
if (reste==14) {LRCascii+='E';}
if (reste==15) {LRCascii+='F';}
std::cout << "LRC : " << LRCascii << std::endl;
return;
}
Examples on what is the input and the result when it is working :
input > ":040100130013??\r\n"
The cout display "LRC : D5"
input > ":0401CD6B05??\r\n"
The cout display "LRC : BE"
D5 and BE are the right results.
I tried with other inputs and had no problem until this :
input > ":0403006B0003??\r\n"
The cout display "LRC : B"
input > ":040306022B00000064??\r\n"
The cout display "LRC : 2"
It should be 8B and not simply B and it should be 62 and not simply 2.
We can see that the last part of the LRC is good but the other part is ignored. What is even stranger is that in this case the cout of "partiehexa" is showing "8" and "6", it is not like this int was empty. I fail to understand why this is happening in this case.
To me it seems to a C code. But I did quickly analyze your code. I Think the problem lies where your are calculating the
(partiehexa < 10)
The LRCascii only gets assigned while looping through the "reste" part of the code. In the "partiehexa" part of the code it do not get assigned to anything.
Suggestion: Change the code to the following and your code will work
if (partiehexa<10)
{
std::stringstream ss3;
ss3 << partiehexa;
ss3 >> temp2;
LRCascii += temp2;
}
Best solution would be to rewrite the code in proper optimized way.
To calculate the LRC
Add up all the data bytes in the message (before converting to ASCII and without the initial colon and final CR/LF).
Throw away any bits that carry over 8 bits.
Make the result negative (by twos compliment) to get the LRC byte.
In your example, checksum can be calculated mathematically as below:
String: 040306022B00000064
Checksum: 62
Byte# 1 Hex Value 04 Decimal Value 4
Byte# 2 Hex Value 03 Decimal Value 3
Byte# 3 Hex Value 06 Decimal Value 6
Byte# 4 Hex Value 02 Decimal Value 2
Byte# 5 Hex Value 2B Decimal Value 43
Byte# 6 Hex Value 00 Decimal Value 0
Byte# 7 Hex Value 00 Decimal Value 0
Byte# 8 Hex Value 00 Decimal Value 0
Byte# 9 Hex Value 64 Decimal Value 100
Total Hex Value 9E Decimal Value 158
LRC: Hex Value FFFFFFFF62 Decimal Value -158
So the single Hex LRC Byte in this example is 62.
Prashant..

Casting in c++ not working as expected

This small program is made to figure out the first and second digits of a 2 digit number. However, when I try using it on the number 99 then it prints 9 and 8, but other 2 digit numbers seem to work fine though. This is probably trivial, but I'm relatively new at programming.
#include <iostream>
using namespace std;
void test(int num) {
float numValue = (num*1.0) / 10;
cout << numValue << endl;
// prints 9.9
int firstDigit = num / 10;
cout << firstDigit << endl;
// prints 9
int secondDigit = (numValue - firstDigit) * 10;
cout << secondDigit << endl;
// prints 8, supposed to be (9.9 - 9) * 10
}
int main()
{
test(99);
return 0;
}
That happens because (numValue - firstDigit) is not exactly 0.9, but rather 0.89999..., because floating-point numbers are not accurate generally. So when you multiply 0.8999... by 10, you get the result of 8.999... However, then you are putting it into an int variable, so it gets trimmed and becomes exactly 8.
You don't really need floating point arithmetic for your exact task though, using integers will be enough.

3 * 8 = 18 in c++

Im getting a slight math error in my program, which is causing problems in the rest of it, and i dont get why it is happening. in this part of the class, i did not overload the operators for built in types (i hope). if i did, please show me where
this function is meant to calculate the least number of bits needed to store a the number, which is stored in a deque <uint8_t> value as one value, so 0x123456 will be stored as {0x12, 0x34, 0x56}, and the output to integer.bits() should be 21
// all types here are standard, so i dont know whats going on
unsigned int bits(){
unsigned int out = value.size() << 3;
std::cout << out << " " << value.size() << " " << (value.size() << 3) << std::endl;
uint8_t top = 128;
while (!(value.front() & top)){
out--;
top >>= 1;
}
return out;
}
yet, this part is couting
8 1 8
16 2 16
...
and finally,
18 3 18
http://ideone.com/zLfz2
3*8 is 24, and in hex that's 0x18. You have std::hex scattered about your code...
Someone has changed your stream to hex and it's printing 24 decimal as 18 hex.