Need help displaying a 2's compliment in 16-bit binary [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Efficiently convert between Hex, Binary, and Decimal in C/C++
Im taking an Assembly Language class and was asked to write an application to accept a signed integer as input and output the corresponding 2's complement. I've been all over the internet trying to find code that would help, but the only thing that I can find is code that converts into exact binary (not the 16-bit format that I need with the leading zeroes). This is the code I have so far:
#include<iostream>
#include<string>
using namespace std;
string binaryArray[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void toBinary(int);
void convertNegative();
int main()
{
cout << "This app converts an integer from -32768 to 32767 into 16-bit 2's complement binary format" << endl;
cout << "Please input an integer in the proper range: ";
int num;
cin >> num;
if (num < -32768 || num > 32767)
cout << "You have entered an unacceptable number, sorry." << endl;
if (num < 0)
{
toBinary(num);
convertNegative();
}
else
toBinary(num);
cout << endl;
system("pause");
return 0;
}
My toBinary function was the function you can find on the internet for decimal to binary, but it only works if I am outputting to the console, and it doesn't work on negative numbers, so I can't take the 2's complement. Any ideas?

To compute the two's complement of a number, you invert the number (change all of its 0 bits to 1, and all of its 1 bits to 0), and then add one. It's that simple. But you'd only need to do that if the number is negative in the first place; the two's complement of a non-negative number is simply the number itself (unconverted).
But you're taking a number as input, and storing it in your variable 'num'. That variable IS in two's complement form. That's how your computer stores it. You don't need to "convert" it to two's complement form at all! If you simply shift the bits off one at a time & print them, you get the two's complement of that number. Just shift them in the right order & pick off the leftmost bit each time, and you've got your solution. It's really short & simple.

Related

How long double fits so many characters in just 12 bytes?

How long double fits so many characters in just 12 bytes?
I made an example, a C ++ factorial
when entering a large number, 1754 for example it calculates with a number that apparently would not fit a long double type.
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
unsigned int n;
long double fatorial = 1;
cout << "Enter number: ";
cin >> n;
for(int i = 1; i <=n; ++i)
{
fatorial *= i;
}
string s = to_string(fatorial);
cout << "Factorial of " << n << " = " <<fatorial << " = " << s;
return 0;
}
Important note:
GCC Compiler on Windows, by visual Studio long double behaves like a double
The problem is how is it stored or the to_string function?
std::to_string(factorial) will return a string containing the same result as std::sprintf(buf, "%Lf", value).
In turn, %Lf prints the entire integer part of a long double, a period and 6 decimal digits of the fractional part.
Since factorial is a very large number, you end up with a very long string.
However, note that this has nothing to do with long double. A simpler example with e.g. double is:
#include <iostream>
#include <string>
int main()
{
std::cout << std::to_string(1e300) << '\n';
return 0;
}
This will print:
10000000000000000525047602 [...300 decimal digits...] 540160.000000
The decimal digits are not exactly zero because the number is not exactly 1e300 but the closest to it that can be represented in the floating-point type.
It doesn't fit that many characters. Rather, to_string produces that many characters from the data.
Here is a toy program:
std::string my_to_string( bool b ) {
if (b)
return "This is a string that never ends, it goes on and on my friend, some people started typing it not knowing what it was, and now they still are typing it it just because this is the string that never ends, it goes on and on my friend, some people started typing it not knowing what it was, and now they still are typing it just because...";
else
return "no it isn't, I can see the end right ^ there";
}
bool stores exactly 1 bit of data. But the string it produces from calling my_to_string can be as long as you want.
double's to_string is like that. It generates far more characters than there is "information" in the double.
This is because it is encoded as a base 10 number on output. Inside the double, it is encoded as a combination of an unsigned number, a sign bit, and an exponential part.
The "value" is then roughly "1+number/2^constant", times +/- one for the sign, times "2^exponential part".
There are only a certain number of "bits of precision" in base 2; if you printed it in base 2 (or hex, or any power-of-2 base) the double would have a few non-zero digits, then a pile of 0s afterwards (or, if small, it would have 0.0000...000 then a handful of non-zero digits).
But when converted to base 10 there isn't a pile of zero digits in it.
Take 0b10000000 -- aka 2^8. This is 256 in base 10 -- it has no trailing 0s at all!
This is because floating point numbers only store an approximation of the actual value. If you look at the actual exact value of 1754! you'll see that your result becomes completely different after the first ~18 digits. The digits after that are just the result of writing (a multiple of) a large power of two in decimal.

recursive c++ factorial giving negative values for multiple entries

I am kind of new to C++ and I am trying to write a recursive factorial calculator. I did write but it is giving multiple negative values for entries like 20, 21, 22, 33, 40, etc. And also the code fails to calculate factorial for integers greater than 65 despite my attempt to enable using long long int. Can someone please explain to me why this is happening? I didn't have any issue in python. Why is it happening in c++?
Here is my code:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
long long int factorial(long int n) {
long long int temp;
if (n == 1 || n == 0) {
return 1;
}
else {
temp = n*factorial(n - 1);
return temp;
}
}
int main()
{
int n, i;
cout << "Enter positive integer or zero: ";
cin >> n;
while (n < 0 || cin.fail()) {
cout << "\nFactorial cannot be calculated for n is negative." << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please try with integer >= 0: ";
cin >> n;
}
cout << factorial(n) << endl;
_getch();
return 0;
}
It's simple overflow issue. You already know the result from python, so you can check if it's too big for the type you're using (obviously it is).
As for python, it has built-in support: Handling very large numbers in Python
Use a C++ bigint library.
What you are experiencing is undefined behavior as a result of integer overflow. you are using a long long int which is a signed integer most likely to be represented as an 8 byte integer (this is platform specific).
Assuming from here one that your long long int is only 8 bytes(64 bits) that would mean that the maximum positive value that it can store is approximately 2^63 which is approx 9.223372037e+18.
Trying to calculate the factorial of numbers like 20, 21, 22, 33, 40, etc will result in a value larger than the maximum that a long long int can store which will result in undefined behavior which in this case is manifesting as integer wraparound.
To fix this you would need to use an integer data type capabale of representing larger values. I would start by switching to an unsigned long long int which will get you twice the range if numbers because an unsigned type deals only in positive numbers. That is just a band-aid on the issue though. To truly handle the problem you will need to find a library that does arbitrary precision integer math. (A bigint library)
(There are also some platform specific things you can do to ask your compiler for a 128bit int, but the better solution is to switch to a bigint data type)
EDIT:
I should clarify that by "bigint" i was not necessarily referring to any particular library. As suggested in the comments there are multiple options as to which library could be used to get the job done.

shifting the binary numbers in c++

#include <iostream>
int main()
{
using namespace std;
int number, result;
cout << "Enter a number: ";
cin >> number;
result = number << 1;
cout << "Result after bitshifting: " << result << endl;
}
If the user inputs 12, the program outputs 24.
In a binary representation, 12 is 0b1100. However, the result the program prints is 24 in decimal, not 8 (0b1000).
Why does this happen? How may I get the result I except?
Why does the program output 24?
You are right, 12 is 0b1100 in its binary representation. That being said, it also is 0b001100 if you want. In this case, bitshifting to the left gives you 0b011000, which is 24. The program produces the excepted result.
Where does this stop?
You are using an int variable. Its size is typically 4 bytes (32 bits) when targeting 32-bit. However, it is a bad idea to rely on int's size. Use stdint.h when you need specific sizes variables.
A word of warning for bitshifting over signed types
Using the << bitshift operator over negative values is undefined behavior. >>'s behaviour over negative values is implementation-defined. In your case, I would recommend you to use an unsigned int (or just unsigned which is the same), because int is signed.
How to get the result you except?
If you know the size (in bits) of the number the user inputs, you can use a bitmask using the & (bitwise AND) operator. e.g.
result = (number << 1) & 0b1111; // 0xF would also do the same

C++ Changing a decimal to octal, output backwards

So I wrote this small application that will convert a decimal to octal, and it is outputting the right answer only it's backwards. An example would be that if the answer to the conversion was 17, the application would display it as 71.
Any help would be much appreciated.
;
int _tmain(int argc, _TCHAR* argv[])
{
int octal, total = 0;
cout<< "please enter a decimal: ";
cin >> octal;
while(octal > 0)
{
total = octal % 8;
octal /= 8;
cout << total;
}
cout << endl;
_getche();
return 0;
}
You can use std::oct to print number in octal notation.
int n = 123;
std::cout << std::oct << n << std::endl;
Similarly you can print number in different notations like decimal - std::dec and hexadecimal - std::hex.
Those input/output manipulators allow user to parse string numbers in various notations.
int n;
std::istringstream("24") >> std::hex >> n;
std::cout << n << std::endl; // n is 36 (decimal)
You need to take a sum and then print the final result, something like
int n=0;
while (octal > 0) {
total += (pow(10,n++))*(octal % 8);
octal /= 8;
}
cout << total << endl;
Just printing the digits will print them in reverse order since you are printing the smallest bits first.
As noted in the comments, the mechanism above will only work for converting to bases smaller than 10.
You are doing fine but you have to print the remainders in reverse order to get the correct answer . For e.g. if ans is 17 then decimal equivalent will be 1*8^1+7*8^0 . unit digit will be the remainder obtained by dividing the number by 8 , next digit to the left will be the remainder obtained by dividing the number by 8^2 and so on. So if the number in octal is of n digit then the most significant digit will be the remainder obtained by dividing the number by 8^n.That is why you have to print the remainder in reverse order.
A solution using an array for temporary storage:
int octal, total = 0, length=0;
char storage[12]; /* 11 octal digits add up to > 1 billion */
octal = 123;
while (octal > 0)
{
storage[length] = octal % 8;
octal /= 8;
length++;
}
while (--length >= 0)
printf ("%d", storage[length]);
printf ("\n");
(I happened to be in C mode, hence the printfs. Change to cout where required.)
The most important point is that you are bound by the storage size. You can set it to a reasonable size -- the largest positive octal size you can put in an integer is 017777777777 --, and even an unreasonable size is acceptable (you can set it to 20, which will only waste 8 additional bytes; these days, that's nothing). The storage size is determined by how big the representation of your number is in octal, for the largest number you can enter.
Suppose you change both 8s to 2; then you can use this same routine for binary output. But at that point, the number of output characters increases to 31! (One less than the [likely] number of bits in your int, because the last bit would toggle the number to negative. You need separate code to handle negative numbers.)
It works as-is for all bases <=10 (including "base 10" itself). If you want to extend the same code to handle bases >10, such as "duodecimal" (base 12) or hexadecimal (base 16), you need to change the printf line. This will make your code work up to base 36 ("sexatrigesimal"). Per convention, "digits" higher than 9 are written A,B,C and so on:
while (--length >= 0)
printf ("%c", storage[length] < 10 ? storage[length]+'0' : storage[length]+'A'-10);
(As I'm making this up as I write, I used the ternary operator ?..:.. for convenience, rather than a separate if..else, which needs more typing. (OTOH, adding the comment negates the gain. Oh well -- at least you learned about the ternary operator, as well as the names for a couple of number bases.))
Another solution is to use recursion. This is a useful method because it doesn't need to preallocate some space in memory -- instead, it relies on the internal call stack.
The principle is that you write a function that only prints the last digit of your number -- but before it does that, unless the remainder is 0, it calls itself with the remainder of the number.
So the function calls itself, then prints the number it should. Because it first calls itself, the called version prints the number it should -- the one to the left of the digit in the "original" function. And so on and so forth, until there is no digit remaining to be printed. From that point on, the last called function prints its number (which is the leftmost digit), returns to the function it was called from, which in turn prints its number (one more to the right), all the way down to the original call.
Recursion is a pretty cool skill to master, so do try this!
Here are two handy functions which might be useful. They return string for each of the conversions. On similar lines to igleyy's answer.
string toOctalFromDecimal (int num) {
ostringstream o;
o << std::oct << num;
return o.str();
}
string toDecimalFromOctal (int num) {
std::ostringstream o;
int x;
std::istringstream(to_string(num)) >> std::oct >> x;
o << std::dec << x;
return o.str();
}

C++ - Unsigned integers

I have the following program written in C++:
The problem with this program is that if the user inputs a negative number, it is NOT caught by the line if(!cin). I thought that unsigned integers can NOT accept negative numbers. Then why if I enter a negative number to size, it is NOT caught by if(!cin) and the program continues execution with no error messages?
I cannot make use of if(size < 0). I want to show how unsigned integers can solve the problem of negative input.
The difference between unsigned and signed integers on most platforms is a sign-bit ... other than that, the actual binary value is the same, it's just interpreted two different ways depending on the sign-ness of the type that the binary value represents. So you can definitely "represent" a negative value input as a unsigned value ... it won't be re-interpreted as that value, but it can definitely be input as that value without an error being set on the stream.
Not a c++ guru or anything but, have you tried using cin.fail() instead of !cin and clear out your buffer with cin.clear()
deeper explaination
C and C++ allow you to assign a negative value to an object of an unsigned type. The result is the original value reduced modulo 2^n, where n is the size of the unsigned type. So, for example, unsigned i = -1; initializes i to UINT_MAX.
The check if(!cin) will only indicate that nothing was read, like the end of a file.
An unsigned integer doesn't force the input to be positive; it just means that the value will always be interpreted as positive (see sign bit), which can have dramatic effects if the number is in fact negative.
Your best bet is probably to input a signed integer and then test in your code whether it is positive.
If you want to prevent the user from entering negative numbers, take input as a signed number and check that it's equal to or greater than zero.
The standard basically says that when you try to assign a number to an integral type that is outside of the range of the type, multiples of the magnitude of the type will be added or subtracted until the value is within the range.
It just so happens that with values expressed as 2-s complement and within the ranges of signed and unsigned ints, this means that the exact same bit pattern will be assigned to any value. Negative one has a bit pattern of all ones, which translates to the highest possible value for the unsigned int, and is equivalent to -1 + 232 or the original value plus the magnitude of an unsigned int.
Or you could just use a larger signed integral type.
long long n = -1;
cout << "Enter a number: ";
cin >> n;
if( !cin.good() )
cout << "Not a valid number." << endl;
else if( n > UINT_MAX )
cout << "Overflow, value is more than UINT_MAX." << endl;
else if( n < 0 )
cout << "Negative, value is less than 0." << endl;
else {
unsigned int m = (unsigned int)n;
cout << "Valid unsigned int was input: " << m << "." << endl;
}