Exceeding C++'s largest integer datatype - c++

I am writing a combinations calculator and for the bigger calculations I end up hitting an overflow with long long int or int64_t. Is it possible to perhaps, at least, convert the number to something of this sort: 6.7090373691429E+19?
Here is my code:
#include <iostream>
#include <string.h>
#include <math.h>
int main() {
std::string charset;
int i, length; int64_t total = 0;
std::cout << "Charset: ";
std::cin >> charset;
std::cout << "Length: ";
std::cin >> length;
for (i=0;i<(length+1);i++) {
total += pow(charset.size(),i);
}
std::cout << "\nPossible combinations: " << total << std::endl;
return 0;
}

The C++ standard library does not include arbitrary size integer types.
You can use Boost Multiprecision for this. It has different backends, using dedicated libraries (e.g. GMP) and a custom backend without external dependencies (cpp_int).
Edit: To be fair, vsoftco already mentioned Boost Multiprecision in a comment.

Related

How to convert char(or string, other type) -> bits?

In c++,
I don't understand about this experience. I need your help.
in this topic, answers saying use to_string.
but they say 'to_string' is converting bitset to string and cpp reference do too.
So, I wonder the way converting something data(char or string (maybe ASCII, can convert unicode?).
{It means the statement can be divided bit and can be processed it}
The question "How to convert char to bits?"
then answers say "use to_string in bitset"
and I want to get each bit of my input.
Can I cleave and analyze bits of many types and process them? If I can this, how to?
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
int main() {
char letter;
cout << "letter: " << endl;
cin >> letter;
cout << bitset<8>(letter).to_string() << endl;
bitset<8> letterbit(letter);
int lettertest[8];
for (int i = 0; i < 8; ++i) {
lettertest[i] = letterbit.test(i);
}
cout << "letter bit: ";
for (int i = 0; i < 8; ++i) {
cout << lettertest[i];
}
cout << endl;
int test = letterbit.test(0);
}
When executing this code, I get result I want.
But I don't understand 'to_string'.
An important point is using of "to_string"
{to_string is function converting bitset to string(including in name),
then Is there function converting string to bitset???
Actually, in my code, use the function with a letter -> convert string to bitset(at fitst, it is result I want)}
help me understand this action.
Q: What is a bitset?
https://www.cplusplus.com/reference/bitset/bitset/
A bitset stores bits (elements with only two possible values: 0 or 1,
true or false, ...).
The class emulates an array of bool elements, but optimized for space
allocation: generally, each element occupies only one bit (which, on
most systems, is eight times less than the smallest elemental type:
char).
In other words, a "bitset" is a binary object (like an "int", a "char", a "double", etc.).
Q: What is bitset<>.to_string()?
Bitsets have the feature of being able to be constructed from and
converted to both integer values and binary strings (see its
constructor and members to_ulong and to_string). They can also be
directly inserted and extracted from streams in binary format (see
applicable operators).
In other words, to_string() allows you to convert the binary bitset to text.
Q: How to to I convert convert char(or string, other type) -> bits?
A: Per the above, simply use bitset<>.to_ulong()
Here is an example:
https://en.cppreference.com/w/cpp/utility/bitset/to_string
Code:
#include <iostream>
#include <bitset>
int main()
{
std::bitset<8> b(42);
std::cout << b.to_string() << '\n'
<< b.to_string('*') << '\n'
<< b.to_string('O', 'X') << '\n';
}
Output:
00101010
**1*1*1*
OOXOXOXO

Why is my output different from input? (C++)

Input : 7182933164
Output : 2147483647
(it isnt all of the code i know there are missing } )
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string line;
ifstream file("Numbers.txt");
int num;
cout << "Enter credit card number : " << endl;
cin >> num;
cout << "enterned : " << num << endl;
Use std:: string to represent code numbers instead.
The value 7182933164 is such a huge number that it crosses the value of the integer it could holds (i.e. -2147483648 to 2147483647). Use long type modifier to accept such values. And if there's only positive integer required, added unsigned before long.
Do something like:
...
long num; // dependent upon the computer architecture
...
If that doesn't works, try long long. Although it's working fine in OnlineGDB (example).

How to take inputs from array and input it into an equation in C++?

My goal is to try and create a program that takes in grades in percents and multiply it with their weight value (either in decimal form or percent form). The equation is basically:
Overall grade = (grade1*weightInDecimal1)+(grade2*weightInDecimal2)+(grade3*weightInDecimal3)+...
or
Overall grade = (grade1*weight%1)+(grade2*weight%2)+(grade3*weight%3)+...
Is there a way to store the inputs and then recall it later in the code? Or possibly a more efficient way?
I also want to try and make a dynamic array. I want to make a program that asks the user for how many assignments they have and makes an array based on that. That way it's not stuck at 4 assignments
#include <string>
#include <iostream>
using namespace std;
int main() {
int numbers[4][2];
for(int i=0;i<4;i++)
{
cout<<"Grade #"<<i<<endl;
cin>>numbers[i][0];
cout<<"Weight for grade #"<<i<<":"<<endl;
cin>>numbers[i][1];
}
for (int i = 0; i<4; i++)
{
cout << "|" << numbers[i][0]*numbers[i][1]<< "|";
}
system ("PAUSE");
return 0;
}
This is what structs are for
#include <string>
#include <iostream>
#include <array>
using namespace std;
struct entry {
int grade;
int weight;
int gradeWeight; //grade*weight
};
int main() {
array<entry,4> numbers;
for(int i=0;i<numbers.max_size();i++)
{
cout<<"Grade #"<<i<<endl;
cin>>numbers[i].grade;
cout<<"Weight for grade #"<<i<<":"<<endl;
cin>>numbers[i].weight;
}
for (int i = 0; i<numbers.max_size(); i++)
{
numbers[i].gradeWeight = numbers[i].grade*numbers[i].weight;
cout << "|" << numbers[i].gradeWeight << "|";
}
system ("PAUSE");
return 0;
}
This way you can also increase the amount of numbers by just increasing the array size.
As pointed by others, if you ask the user for how many assignments they have, std::array is a wrong container because it's dimension is fixed at compile time.
As others, I discurage the use of direct memory allocation but the use of std::vector to manage it.
I just suggest the use of reserve() (method of std::vector), when you know how many assignments.
The following is a full example using, instead a couple of std::vector of int, a single std::vector of std::pair<int, int>
#include <utility>
#include <vector>
#include <iostream>
int main()
{
int valG, valW;
std::size_t dim;
std::vector<std::pair<int, int>> vec;
std::cout << "How many grade/weight couples? ";
std::cin >> dim;
vec.reserve(dim);
for ( auto i = 0U ; i < dim ; ++i )
{
std::cout << "Grade #" << i << "? " << std::endl;
std::cin >> valG;
std::cout << "Weight for grade #" << i << "? " << std::endl;
std::cin >> valW;
vec.emplace_back(valG, valW);
}
for ( auto const & p : vec )
std::cout << '|' << (p.first * p.second) << '|';
std::cout << std::endl;
return 0;
}
There are many reasons to avoid using arrays (dynamic or otherwise). See for example Stroustrup's FAQ entry What's wrong with arrays? As Greg suggests in the comments you will most likely write better quality code if you use a container like std::vector.
If you can calculate or input the size of your container before allocating it you can (if you wish) pass that size to the constructor ...
auto syze{ 0 };
auto initialValue{ 0 };
// calculate or input syze
. . .
// dynamically allocate an "array"
// of ints and an "array" of floats
std::vector<int> grades(syze, initialValue);
std::vector<float> weights(syze, initialValue);
On the other hand if you prefer to use a container that dynamically grows to hold data as it arrives you can do that too...
// dynamically allocate an empty "array"
// of ints and an empty "array" of floats
std::vector<int> grades;
std::vector<float> weights;
while (...condition...)
{
std::cin >> g; // input a grade ...
std::cin >> w; // ... and a weight
// grow the containers by adding
// one item at the end of each
grades.emplace_back(g);
weights.emplace_back(w);
}
Update
I should have pointed out how to calculate the result from the two vectors. You can calculate your overall grade with just one more line of code by using std::inner_product from the STL's <numeric> header. Note that in the code below the last argument is 0.0 (rather than just 0) so that std::inner_product returns a double rather than an int. That avoids any risk of float values being truncated to int (and avoids some pretty ugly warnings from the compiler).
auto overallGrade = std::inner_product(grades.begin(), grades.end(), weights.begin(), 0.0);

C++: reading a string, converting to dynamic int array

I am writing a program that asks the user to type in a very large int (much larger than the type int can handle). When receive this int from the user, it is stored in a string. Then, I want to convert this string into an int array (I am using a dynamic int array). After compiling and running the program, I get values that don't make sense. The values of my int array seem to be random gibberish. I don't see why this is so - it doesn't look like my loops are out of bound in the converting process. Please help. The purpose of creating an int array is to then come up with ways to add, subtract, multiply, and compare very large int values. To make it clear what I am intending to do: say the user types in "12345". I want to store this string value into an int array that would have a length of 5, each element corresponding to the next number in the int.
largeIntegers.h
#ifndef H_largeIntegers
#define H_largeIntegers
#include <iostream>
#include <string>
class largeIntegers
{
private:
void readInteger();
// reads integer
public:
std::string s_integer;
int* integer;
int length;
largeIntegers();
// default constructor
void outputInteger();
// outputs integer
};
#endif
largeIntegers.cpp
#include <iostream>
#include <string>
#include "largeIntegers.h"
using namespace std;
largeIntegers::largeIntegers()
{
readInteger();
}
void largeIntegers::readInteger()
{
int i = 0,j = 0, k;
cout << "Enter large integer: ";
cin >> s_integer;
for (; s_integer[i] != '\0'; i++);
length = i;
int* integer = new int[i];
k = 0;
for (j = i - 1; j >= 0; j--)
integer[j] = s_integer[k++] - 48;
}
void largeIntegers::outputInteger()
{
for (int i = length - 1; i >= 0; i--)
cout << integer[i];
}
User.cpp
#include <iostream>
#include <string>
#include "largeIntegers.h"
using namespace std;
int main()
{
largeIntegers a;
cout << a.length << endl << endl;
cout << a.integer[0] << endl << a.integer[1] << endl;
a.outputInteger();
cout << endl << endl;
return 0;
}
I intentionally made the variables in the header public for debugging purposes. My output on the console after compiling is:
Enter large integer: 111
3
952402760
1096565083
10966961571096565083952402760
This is the problem
int* integer = new int[i];
change to
integer = new int[i];
Your version declares a local variable that just happens to have the same name as your class variable. Easy mistake to make.
also, using standards facilities like std::vector and std::getline would make your code much cleaner in addition to avoid the problem you had, and resolve memory leaks you have now if you call readInterger twice:
void largeIntegers::readInteger()
{
cout << "Enter large integer: ";
std::getline(std::cin, s_integer);
integer = std::vector(s_integer.size());
//your last loop to fill the array probably can be replaced by std::transform
}

How to force a preceding 0 to an int (without actually outputting it)

So I'm trying to force a preceding 0 to an int so it can be processed later on. Now, all the tutorials i've seen on SO, or any other website, all use something similar to this:
cout << setfill('0') << setw(2) << x ;
Whilst this is great, i can only seem to get it to work with cout, however, I don't want to output my text, i just want the number padded, for later use.
So far, this is my code..
#include <iostream>
#include <string>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <sstream>
/*
using std::string;
using std::cout;
using std::setprecision;
using std::fixed;
using std::scientific;
using std::cin;
using std::vector;
*/
using namespace std;
void split(const string &str, vector<string> &splits, size_t length = 1)
{
size_t pos = 0;
splits.clear(); // assure vector is empty
while(pos < str.length()) // while not at the end
{
splits.push_back(str.substr(pos, length)); // append the substring
pos += length; // and goto next block
}
}
int main()
{
int int_hour;
vector<string> vec_hour;
vector<int> vec_temp;
cout << "Enter Hour: ";
cin >> int_hour;
stringstream str_hour;
str_hour << int_hour;
cout << "Hour Digits:" << endl;
split(str_hour.str(), vec_hour, 1);
for(int i = 0; i < vec_hour.size(); i++)
{
int_hour = atoi(vec_hour[i].c_str());
printf( "%02i", int_hour);
cout << "\n";
}
return 0;
}
The idea being to input an int, then cast it to a stringstream to be split into single characters, then back to an integer. However, anything less than the number 10 (<10), I need to be padded with a 0 on the left.
Thanks guys
EDIT:
The code you see above is only a snippet of my main code, this is the bit im trying to make work.
Alot of people are having trouble understanding what i mean. so, here's my idea. Okay, so the entire idea of the project is to take user input (time (hour, minute) day(numeric, month number), etc). Now, i need to break those numbers down into corresponding vectors (vec_minute, vec_hour, etc) and then use the vectors to specify filenames.. so like:
cout << vec_hour[0] << ".png";
cout << vec_hour[1] << ".png";
Now, i know i can use for loops to handle the output of vectors, i just need help breaking down the input into individual characters. Since i ask users to input all numbers as 2 digits, anything under the number 10 (numbers preceding with a 0), wont split into to digits because the program automatically removes its preceding 0 before the number gets passed to the split method (ie. you enter 10, your output will be 10, you enter 0\n9, and your output will be a single digit 9). I cant have this, i need to pad the any number less than 10 with a 0 before it gets passed to the split method, therefore it will return 2 split digits. I cast the integers into stringstreams because thats the best way for splitting data types i found (incase you were wondering).
Hope i explained everything alot better :/
If I understand correctly your question, you can just use those manipulators with a stringstream, for instance:
std::stringstream str_hour;
str_hour << setfill('0') << setw(2) << int_hour;
String streams are output streams, so I/O manipulators affect them the same way they affect the behavior of std::cout.
A complete example:
#include <sstream>
#include <iostream>
#include <iomanip>
int main()
{
std::stringstream ss;
ss << std::setfill('0') << std::setw(2) << 10; // Prints 10
ss << " - ";
ss << std::setfill('0') << std::setw(2) << 5; // Prints 05
std::cout << ss.str();
}
And the corresponding live example.
int and other numeric types store values. Sticking a 0 in front of an integer value does not change the value. It's only when you convert it to a text representation that adding a leading 0 changes what you have, because you've changed the text representation by inserting an additional character.
X-Y Problem, I think
for ( int i = 0; i < POWER_OF_TEN; i++ )
{
vector<int>.push_back(num%10);
num /= 10
}
?
Then reverse the vector if you want
yes i know this is not real code
if you really want characters, vector<char>.push_back(num%10 + '0')?