I'm writing a C++ program that converts a decimal number to binary and hexadecimal.
The problem is that for some reason it concatenates the number "1875954912" to both representations every time.
I've tried a bunch of things - mainly changing up how the program calculates numArrayLength and the for-loop in my decToBase function, but I haven't been able to figure out why this happens yet.
The program is not complete by the way - it doesn't turn integers bigger than 9 into letters for the hex representation yet, but that's not my main concern right now.
Here is my code:
#include <iostream>
#include <cmath>
using namespace std;
int howManyBitsNeeded(int someNum, int base) {
int numOfDivisions = 0;
while (someNum != 0) {
someNum = floor(someNum / base);
numOfDivisions += 1;
}
return numOfDivisions;
}
int decToBase(int someNum, int base) {
int bitsNeeded = howManyBitsNeeded(someNum,base);
int numArrayLength = bitsNeeded;
int numArray[bitsNeeded];
while (bitsNeeded > 0) {
numArray[bitsNeeded] = (someNum % base);
someNum = floor(someNum / base);
bitsNeeded -= 1;
}
for (int k = (numArrayLength-1); k >= 0; --k) {
cout << numArray[(numArrayLength - k)];
}
}
int main() {
int inpNum;
cout << "Enter your number: ";
cin >> inpNum;
cout << "Binary representation: " << decToBase(inpNum,2) << endl;
cout << "Hexadecimal representation: " << decToBase(inpNum,16);
return 0;
}
And here's what the output looks like:
Enter your number: 25
Binary representation: 110011875954912
Hexadecimal representation: 191875954912
Any help would be greatly appreciated!
Your decToBase is declared as returning an int, but it doesn't actually return anything. Your compiler should warn you about this. Since you're not returning anything here, change its return type to void. Then instead of trying to print its return value, simply call the function without printing it:
std::cout << "Binary representation: ";
decToBase(inpNum, 2); // this already prints the number, no need to pass it to std::cout
std::cout << endl;
std::cout << "Hexadecimal representation: ";
decToBase(inpNum, 16);
std::cout << std::endl;
Or of course you can change the function to return the string that you want to print instead of printing it inside the function.
Also, there's an issue here:
int numArray[bitsNeeded];
This is out of range when you try to access it here:
while (bitsNeeded > 0) {
numArray[bitsNeeded] = (someNum % base);
And also later when you try to print it. To get rid of this off by one error, you have to change this to
numArray[bitsNeeded-1] = (someNum % base);
And in the output change it to
cout << numArray[(numArrayLength - k -1)];
And while you're at it, instead of having it as a VLA (which isn't part of C++ and only works if the compiler tolerates it), I would recommend a vector:
std::vector<int> numArray(bitsNeeded+1); // include <vector> for this to work
Furthermore, note that integer division is already truncated, so unless you plan to support negative numbers later on, you can silence a warning about implicit double to int conversion by changing this:
someNum = floor(someNum / base);
To this:
someNum /= base;
Related
I'm trying to convert a for loop to while loop in c++ and do some checking for duplicates in a random number generator for generating lotto numbers so far all the stuff i'm trying seems to make the compiler very unhappy and I could really use a few pointers. It's the for loop in the Harray() function that feeds the Balls[] array
that i want to convert to a while loop.
#include<iostream>
#include<cstdlib> // to call rand and srand.
#include<ctime> // to make rand a bit more random with srand(time(0)) as first call.
#include<iomanip> // to manipulate the output with leading 0 where neccesary.
using namespace std;
// Hrand() function create and return a random number.
int Hrand()
{
int num = rand()%45+1; // make and store a random number change 45 for more or less Balls.
return num; // return the random number.
}
// Harray() function create and fill an array with random numbers and some formatting.
void Harray()
{
int Balls[6]; // change the number in Balls[6] and in the for loop for more or less nrs. a row.
for(int x=0; x<=6; x++) //the loop to fill array with random numbers.
{
int a; // made to pass the Balls[x] data into so i can format output.
int m = Hrand(); // calling the Hrand() function and passing it's value in int m.
Balls[x] = m; // throwing it into the array tought i did this because of an error.
a = Balls[x]; // throwing it into int a because of an type error.
cout<<"["<<setfill('0')<<setw(02)<<a<<"]"; //format output with leading 0 if neccesary.
}
cout<<endl; // start new row on new line.
}
// Main function do the thing if compiler swallows the junk.
int main() // start the program.
{
int h; // int to store user cchoice.
srand(time(0)); // make rand more random.
cout<<"How many rows do you want to generate?"<<endl; // ask how many rows?
cin>>h; // store user input.
for(int i=h; h>0; h--) // produce rows from user input choice.
{
Harray(); // calling Harray function into action.
}
return 0; // return zero keep the comipler happy.
}
I would like to always have six diffrent numbers in a row but i don't see how to get there with the for loops i think the while loop is way to go but am open to any suggestion that will work. I'm just starting with c++ i might have overlooked some options.
int x=0;
while(x<6)
{
int a;format output.
int m = Hrand();value in int m.
Balls[x] = m; because of an error.
a = Balls[x];
cout<<"["<<setfill('0')<<setw(02)<<a<<"]";
x++;
}
Here, I also fixed a bug. Since Balls has 6 elements, the last element will be 5. Thus you want x<6 instead of x<=6. That goes for the for loop too.
One drawback of while loops is that you cannot declare local variables with them.
First of all, you should realize that the difference between a for loop and a while loop is mostly syntactic--anything you can do with one, you can also do with the other.
In this case, given what you've stated as your desired output, what you probably really want is something like this:
std::vector<int> numbers;
std::set<int> dupe_tracker;
while (dupe_tracker.size() < 6) {
int i = Hrand();
if (dupe_tracker.insert(i).second)
numbers.push_back(i);
}
The basic idea here is that dupe_tracker keeps a copy of each number you've generated. So, you generate a number, and insert it into the set. That will fail (and return false in retval.second) if the number is already in the set. So, we only add the number to the result vector if it was not already in the set (i.e., if it's unique).
How convert for-loop to while-loop
#include <iostream>
class T545_t
{
// private data attributes
int j;
public:
int exec()
{
// A for-loop has 3 parameters, authors often fill 2 of them with magic
// numbers. (magic numbers are usually discouraged, but are expected
// in for-loops)
// Here, I create names for these 3 for-loop parameters
const int StartNum = 2;
const int EndNum = 7;
const int StrideNum = 2;
std::cout << std::endl << " ";
for (int i = StartNum; i < EndNum; i += StrideNum ) {
std::cout << i << " " << std::flush;
}
std::cout << std::flush;
// A while-loop must use / provide each of these 3 items also, but
// because of the increased code-layout flexibility (compared to
// for-loop), the use of magic numbers should be discouraged.
std::cout << std::endl << " ";
j = StartNum;
do {
if (j >= EndNum) break;
std::cout << j << " " << std::flush;
j += StrideNum;
} while(true);
std::cout << std::flush;
std::cout << std::endl << " ";
j = StartNum;
while(true) {
if (j >= EndNum) break;
std::cout << j << " " << std::flush;
j += StrideNum;
}
std::cout << std::flush;
std::cout << std::endl << " ";
j = StartNum;
while(j < EndNum) {
std::cout << j << " " << std::flush;
j += StrideNum;
}
std::cout << std::endl;
return 0;
}
}; // class T545_t
int main(int , char** )
{
T545_t t545;
return(t545.exec());
}
Ask me where 'j' is declared?
This code is marked as C++, so in this case, I have declared 'j' in the private data attribute 'section' of this class definition. That is where you'd look for it, right?
If your c++ code does not have class, what's the point?
I'm currently having a problem making a code for a Coordinate system.
In the exercise I'm doing, I want to create a coordinate system with an Ordinate/Abscissa and a defined letter (for example dot A)
I must put information for 25 dots and it must control all dots with the same letter. They should be in a circle with a (0;0) coordinate beginning. If the information given about the 25 dots do not meet the set condition the selected dots must have new reentered information to meet the condition without changing the given values of the previous dots(which meet the expectations). It also should have all the information for dots which have 2 positive coordinates
here's the code I made. I'd be really thankful if someone helped me out.
#include <iostream>
#include <cmath>
#include <stdio.h>
using namespace std;
int main(){
int dotX[23];//tri masiva
int dotY[23];
char dotName[23];
for (int i = 0; i<23; i++){// Cikal za vavejdane na masivite
cout << "Abscisa \t" << i + 1 << endl;
cin >> dotX[i];
cout << "Ordinata \t" << i + 1 << endl;
cin >> dotY[i];
cout << "Ime na tochkata" << endl;
cin >> dotName[i];
if (i >= 1){//IF operatora i cikula za obhozhdane na masiva i presmqtane na distanciite
bool flag = true;
while (flag){
double distance = sqrt(pow(dotY[i] - dotY[i - 1], 2) + pow(dotX[i] - dotX[i - 1], 2));//Formula za presmqtane na razstoqniqta
if (distance <= 6) {
char broi;
broi = broi++;
cout << "abscisa \t" << i + 1 << endl;
cin >> dotX[i];
cout << "ordinata \t" << i + 1 << endl;
cin >> dotY[i];
}
else{
flag = false;
}
}
}
}
float i;
for (float i = 0; i > 10, i++;){
float(dotX < 10);
cout << dotName[i] << endl;
}
}
There are a few big problems with your code.
First of all, the syntax for (float i = 0; i > 10, i++;) is completely wrong. It compiles, but that's just a coincidence. The different command in the for loop control structure should be separated by semicolons (;), not commas (,). The correct code would then be for (float i = 0; i > 10; i++). By the way, you made a typo, I think you meant for (float i = 0; i < 10; i++) (otherwise the for loop never runs since i is initialized to 0 and 0 > 10 is false from the beginning).
Second of all, you're initializing the variable i twice: once with float i; and once in the for loop. That shouldn't compile, although with some compilers it does. There are two options on how to do. The first option is to declare the variable outside of the for loop and just assign it without initializing it in the for loop:
float i;
for(i = 0; i < 10; i++){
//some stuff
}
The second option is to simply declare it in the for loop as you did in the first loop:
for(float i = 0; i < 10; i++){
//some stuff
}
Another mistake that you made is to declare i as a float and then try to access dotName[i]. Whatever you put inside the brackets has to be of type int or something similar (unsigned int, long, etc). Putting a float variable inside those brackets won't compile just like that. If you want to index an array with a float, you need to tell the compiler that you want to convert it to an int like this: dotName[(int)i] or dotName[int(i)]. This is called a cast. However, in your case, I would recommend just declaring i as an int.
Also, float(dotX < 10); is completely wrong, I don't really understand what you're trying to do there. I think you meant to do float(dotX[i] < 10);, but that still doesn't make any sense. What you would be doing there would be converting a bool to a float and then doing nothing with the result. That compiles and isn't wrong, but is completely useless. As I said, I don't understand what you want to do there.
Also, broi = broi++; is correct but useless. broi++; is enough. The ++ operator increments broi by one by itself and then returns the result. What the ++ operator does internally is basically this:
int operator++(int &x){
x = x + 1;
return x;
}
So it already increments the variable automatically without you having to do anything. What you did is the same as doing this:
broi = broi + 1;
broi = broi;
Here, the first line represents the ++ operator and the second line represents the = operator. It's clear that the second line is useless, so you can just remove it. In the same way, in your code, you can remove broi =, leaving simply broi++;.
You also did a few things that aren't recommended, but work just fine since the C++ standard supports them.
First of all, using namespace std; is bad practice. It's recommended to omit it and add std:: in front of cin, cout and endl. If you want to know why using namespace std; is bad practice, it's well explained here. However, I must admit that I personally still use using namespace std; since I think it's simpler.
Second of all, the main function is supposed to return 0, so it's recommended to add return 0; at the end of the main function. The return value of the main function tells what made the program close. The value 0 means that the program closed when it was supposed to. Any other values mean that the program crashed. A complete list of what each return value means is available here. Note that C++ supports omitting return 0; and most compilers add it automatically if it is omitted, but it's still recommended to have it. Also, C doesn't support omitting return 0; and in C it will return whatever happens to be in the memory, making it looked like the program crashed when it ended normally.
Also, #include <stdio.h> is C and although it works in C++, it's not recommended. In C++, it's better to use #include <cstdio>. All standard libraries that end with .h in C can be used in C++ by removing .h and adding a c at the beginning. That's also the case with cmath: in C, it would be #include <math.h> and in C++, it's #include <cmath>.
A good version of your code would therefore be:
#include <iostream>
#include <cmath>
#include <cstdio>
int main(){
int dotX[23]; //tri masiva
int dotY[23];
char dotName[23];
for (int i = 0; i < 23; i++){ // Cikal za vavejdane na masivite
std::cout << "Abscisa \t" << i + 1 << std::endl;
std::cin >> dotX[i];
std::cout << "Ordinata \t" << i + 1 << std::endl;
std::cin >> dotY[i];
std::cout << "Ime na tochkata" << std::endl;
std::cin >> dotName[i];
if (i >= 1){ //IF operatora i cikula za obhozhdane na masiva i presmqtane na distanciite
bool flag = true;
while (flag){
double distance = sqrt(pow(dotY[i] - dotY[i - 1], 2) + pow(dotX[i] - dotX[i - 1], 2)); //Formula za presmqtane na razstoqniqta
if (distance <= 6) {
char broi;
broi++;
std::cout << "abscisa \t" << i + 1 << std::endl;
std::cin >> dotX[i];
std::cout << "ordinata \t" << i + 1 << std::endl;
std::cin >> dotY[i];
}
else{
flag = false;
}
}
}
}
for (int i = 0; i < 10; i++){
float(dotX[i] < 10); //Note that I don't understand what you're trying to do here, so I just changed it to something that compiles
std::cout << dotName[i] << std::endl;
}
}
Whilst working on a personal project of mine, I came across a need to divide two very large arbitrary numbers (each number having roughly 100 digits).
So i wrote out the very basic code for division (i.e., answer = a/b, where a and b are imputed by the user)and quickly discovered that it only has a precision of 16 digits! It may be obvious at this point that Im not a coder!
So i searched the internet and found a code that, as far as i can tell, uses the traditional method of long division by making a string(but too be honest im not sure as im quite confused by it). But upon running the code it gives out some incorrect answers and wont work at all if a>b.
Im not even sure if there's a better way to solve this problem than the method in the code below!? Maybe there's a simpler code??
So basically i need help to write a code, in C++, to divide two very large numbers.
Any help or suggestions are greatly appreciated!
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std; //avoids having to use std:: with cout/cin
int main (int argc, char **argv)
{
string dividend, divisor, difference, a, b, s, tempstring = ""; // a and b used to store dividend and divisor.
int quotient, inta, intb, diff, tempint = 0;
char d;
quotient = 0;
cout << "Enter the dividend? "; //larger number (on top)
cin >> a;
cout << "Enter the divisor? "; //smaller number (on bottom)
cin >> b;
//making the strings the same length by adding 0's to the beggining of string.
while (a.length() < b.length()) a = '0'+a; // a has less digits than b add 0's
while (b.length() < a.length()) b = '0'+b; // b has less digits than a add 0's
inta = a[0]-'0'; // getting first digit in both strings
intb = b[0]-'0';
//if a<b print remainder out (a) and return 0
if (inta < intb)
{
cout << "Quotient: 0 " << endl << "Remainder: " << a << endl;
}
else
{
a = '0'+a;
b = '0'+b;
diff = intb;
//s = b;
// while ( s >= b )
do
{
for (int i = a.length()-1; i>=0; i--) // do subtraction until end of string
{
inta = a[i]-'0'; // converting ascii to int, used for munipulation
intb = b[i]-'0';
if (inta < intb) // borrow if needed
{
a[i-1]--; //borrow from next digit
a[i] += 10;
}
diff = a[i] - b[i];
char d = diff+'0';
s = d + s; //this + is appending two strings, not performing addition.
}
quotient++;
a = s;
// strcpy (a, s);
}
while (s >= b); // fails after dividing 3 x's
cout << "s string: " << s << endl;
cout << "a string: " << a << endl;
cout << "Quotient: " << quotient << endl;
//cout << "Remainder: " << s << endl;
}
system ("pause");
return 0;
cin.get(); // allows the user to enter variable without instantly ending the program
cin.get(); // allows the user to enter variable without instantly ending the program
}
There are much better methods than that. This subtractive method is arbitrarily slow for large dividends and small divisors. The canonical method is given as Algorithm D in Knuth, D.E., The Art of Computer Programming, volume 2, but I'm sure you will find it online. I'd be astonished if it wasn't in Wikipedia somewhere.
I've been trying to create a program in C++ that tries to accomplish this pseudocode:
get argv[1] into int
get int’s digits into array[int length]
for int i = array length; i >= 0;
gen random number into check
if check == array[i]
i
say Number i was check
end if
And I think the part I'm really struggling with is the
get argv[1] into int
get int’s digits into array[int length]
part. In my full code there isn't even an attempt because nothing I've tried works. The error I get the most is that the code compiles, but everytime it tries to cout << "Number 1:" << number I just get Number 1: 0 no matter the actual number I enter. And when 0 == 0 the code doesn't even notice.
My broken propably convention-breaking code follows:
#include <iostream>
#include <string>
int main (int argc, char **argv) {
if (argc == 1 || argc == 3) {
std::cout << "Argument count does not match (one argument expected)\n";
return(-1);
}
std::cout << "Input: " << argv[1] << "\n";
const char* text = argv[1];
int number = atoi(text);
int check = rand() % 10;
std::cout << "Check 1: " << check << "\nNumber 1: " << number << "\n";
if (check == array[i]) {
i++;
std::cout << "Success! Number " << i << " was " << check << ".\n";
}
}
}
TL;DR: My "sort of" number cracker doesn't want to put argv1 into an int with the int's digits being later put into an array.
Feel free to make me feel stupid. Hope the question isn't too specific. I'll expand on details as asked.
EDIT: This is an earlier attempt at conversion:
int array[];
for (int i = strlen(text); i >= 0; i--) {
array[i] = number % 10;
number /= 10;
}
EDIT2: So many responses, no solutions. Thank you for trying to explain this newbie so many things at once. BTW: Git
The earlier attempt is almost good: it's just that you have to actually allocate space for the array, like this:
int array[strlen(text)];
if your compiler supports variable-length arrays as an extension, and
std::vector<int> array;
array.resize(strlen(text));
if you want to stick with standard C++ and follow some good practices.
However, if you want to be tricky, you don't even need to convert the argument to a number:
if (argv[1][i] == check % 10 + '0')
does the trick too. All in all, the complete program would look like this:
#include <iostream>
#include <cstdlib>
int main(int argc, char *argv[])
{
int check = std::rand();
std::cout << check << std::endl;
char *p = argv[1] + strlen(argv[1]);
while (p - argv[1] >= 0) {
if (*--p == '0' + check % 10)
std::cout << "guessed " << p - argv[1] << "th digit" << std::endl;
check /= 10;
}
return 0;
}
Your code is relatively close to being right. You are struggling with the declaration of the array (you must specify the size for it). 32-bit int cannot have more than ten digits, so declaring
int array[10];
should be sufficient.
Before converting the number to an array of digits, check if it is negative, and flip its sign if it is negative:
if (number < 0) {
number = -number;
}
Otherwise, your number%10 trick is not going to work.
When you do the conversion, count how many digits you have. Put the result in actualCount variable: chances are that you are not going to use up all the digits in your array, so
int check = rand() % 10; // 10 is the max, not the actual digit count
should be
int check = rand() % actualCount;
Your argument checking also needs improvement: think what would happen if the user passes five parameters? If you expect exactly one argument, you should write
if (argc != 2) {
std::cout << "Argument count does not match (one argument expected)\n";
return(-1);
}
In order to extract only one digit at a time from a number you have a couple of choices.
For convenience you can use a std::string, inserting the original string (argv[1]) in it, then extracting one char at a time:
#include <string>
...
// put the input in a string
std::string text = argv[1];
for (unsigned i = 0; i < text.size(); i++)
{
// extract only one char, a digit
char ch = text.at(i);
// convert that char in a number
int n = ::atoi(& ch);
// use n
...
}
If you don't want to use std::string, you can always use a c-like array (argv[1] itself):
#include <cstring>
...
for (unsigned i = 0; i < strlen(argv[1]); i++)
{
// extract only one char, a digit
char digit = argv[1][i];
// convert that char in a number
int num = ::atoi(& digit);
// use n
...
}
I have to convert decimal numbers like 43.62 to binary. So i first wrote a basic program that converts 43 into binary. But I notice that my program prints out the binary number in reverse, so it prints 1 1 0 1 0 1 instead of 1 0 1 0 1 1. how can I fix this.
My Code:
#include <iostream>
using namespace std;
int main()
{
int number;
int remainder;
cout << "Enter a integer: ";
cin >> number;
while(number != 0)
{
remainder = number % 2;
cout << remainder << " ";
number /= 2;
}
int pause;
cin >> pause;
return 0;
}
Instead of sending each digit to cout, send them to an array. Then read the array out in reverse order. Or push them onto a stack, and then pop them back off the stack. Or...
Something of a sledgehammer to crack a nut, but here's a solution based on a recursive approach:
#include <iostream>
using namespace std;
void OutputDigit(int number)
{
if (number>0)
{
OutputDigit(number /= 2);
cout << number % 2 << " ";
}
}
int main()
{
OutputDigit(43);
return 0;
}
You can get the same output as you had before by simply moving the cout one line up!
Look at vector and think about how it could be useful to save the remainders instead of printing them right away.
Notice that you don't have to put things at the end of the vector. vector::insert lets you specify a position... could that be helpful?
Alternatively, the algorithm you created starts at the least significant digit. Is there a way to start from the most significant digit instead? If I have the number 42 (0101010), the most significant digit represents the 32s, and the 0 ahead of it represents the 64s. What happens if I subtract 32 from 42?
It would be easier to store the results and then print them backwards. Using recursion is also another possibility to do just that.
Most significant bit first:
const unsigned int BITS_PER_INT = CHAR_BIT * sizeof(int);
char bit_char = '0';
for (int i = BITS_PER_INT - 1;
i > 0;
--i)
{
bit_char = (value & (1 << i)) ? '1' : '0';
cout << bit_char << ' ';
}
cout << '\n';
cout.flush();
To print least significant bit first, change the direction of the for loop.
In C++, you can also use a bitset container to do this,
#include <bitset>
int i = 43;
std::bitset<sizeof(int)*CHAR_BIT> bin(i);
Just use string functions
string s ;
while(number != 0)
{
remainder = number % 2;
string c = remainder ? "1": "0";
s.insert(s.begin(),c.begin(),c.end());
number /= 2;
}
When you do such conversion by holding on to the remainder, the result will always be reverted. As suggested use bitwise &:
unsigned char bit = 0x80; // start from most significant bit
int number = 43;
while(bit)
{
if( bit & number ) // check if bit is on or off in your number
{
cout << "1";
}
else
{
cout << "0";
}
bit = bit >>1; // move to next bit
}
This example will start going through all your 8 bits of the number and check if the bit is on or off and print that accordingly.
Best option - Use C++ stringstream for formatting I/O
// Add the following headers
#include <sstream>
#include <algorithm>
// your function
stringstream ss;
// Use ss in your code instead of cout
string myString = ss.str();
std::reverse(myString.begin(),myString.end());
cout << myString;