Use non-const variable in place of required const variable (C++) - c++

Part of a program I'm writing involves getting a list of integers (e.g. 15, 18, 25) and converting each one to binary. I'm iterating through the list and using the following line of code to convert each one:
std::string binary = std::bitset<8>(v).to_string();
(the (v) is the integer I'm converting)
but the problem with this line of code is that it defines the length of the outputted binary string, so 2 would become "00000010" and 31 would become "00011111" of course I cant it make too low or else im going to have some trouble with larger numbers, but I want the length of each binary string to be equal to the real binary number (2 is "10", 31 is "11111"). I have my reasons for this.So I tried replacing the <8> with an int that changes based on the number I'm trying to convert based on the following code:
int length_of_binary;
if (v <= 1) {
length_of_binary = 1;
}
else if (v <= 3) {
length_of_binary = 2;
}
else if (v <= 8) {
length_of_binary = 4;
}
else if (v <= 16) {
length_of_binary = 5;
}
else if (v <= 32) {
length_of_binary = 6;
}
std::string binary = std::bitset<length_of_binary>(v).to_string();
The problem is that i get the following error when hovering over the (now under-waved) variable length_of_binary:
"+5 overloads. expression must have a constant value."
and the program won't compile. I even tried tricking the compiler by assigning
the value of length_of_binary to a const int but it still won't work. Is there a way to fix this? if not is there a piece of code/function that will give me what I need?

As already mentioned in the comments: the issue you face is that the value needs to be known at compile time (not runtime dependent).
Hence, you can use a fixed representation, for example std::bitset<N> convert it into a string like you have already done and then trim the leading zeros.
It can be achieved like this:
std::string text = std::bitset<8>(25).to_string(); // binary representation
text.erase(0, text.find_first_not_of('0')); // zeroes trimmed
std::cout << text; // prints out: 11001
Note that this is just an example. You would still have to handle the case of 0 and think whether your input data won't exceed an 8 bit representation.
Nevertheless, with this approach you have no need for the length_of_binary variable and the related if-else sections - which simplifies the code a lot.

Related

I just created an extremely fast way to sort primes. How do I improve it?

Basically, how it works is it converts a number into a string, and if it finds any even in the string then it gives foundEven variable a positive value. The same goes for odd numbers.
(One thing I don't get is why if I switch the '>' sign with an '<' in if (FoundEvenSignedInt < FoundOddSignedInt) it gives you the correct result of an odd number.)
Are there any ways I could improve the code? Are there any bugs in it? I'm fairly new at C++ programing.
#include <string>
#include <cstddef>
int IsPrime(long double a)
{
int var;
long double AVar = a;
signed int FoundEvenSignedInt, FoundOddSignedInt;
std::string str = std::to_string(a);
std::size_t foundEven = str.find_last_of("2468");
std::size_t foundOdd = str.find_last_of("3579");
FoundEvenSignedInt = foundEven;
FoundOddSignedInt = foundOdd;
if (FoundEvenSignedInt < FoundOddSignedInt)
{
var = 1;
goto EndOfIsPrimeFunction;
}
if (FoundEvenSignedInt > FoundOddSignedInt)
{
var = 2;
goto EndOfIsPrimeFunction;
}
// This if statement kept giving me this weird warning so I made it like this
if (FoundEvenSignedInt == -1)
{
if (FoundOddSignedInt == -1)
{
if (AVar == 10 || 100 || 1000 || 10000 || 100000 || 1000000)
{
var = 2;
goto EndOfIsPrimeFunction;
}
}
}
EndOfIsPrimeFunction:
return var;
}
Here are some ways to improve the code.
The Collatz conjecture is about integers. long double is a data type of floating point numbers. It is unsuitable for checking the conjecture. You need to work with an integral data type such as unsigned long long. If this doesn't have enough range for you, you need to work with some kind of Bignum dat atype. There isn't any in the standard C library, you need to find a third party one.
The Collatz conjecture has nothing to do with being prime. It is about even and odd integers. It is true that all prime numbers except 2 are odd, but this fact doesn't help you.
The data type to answer yes/no questions in C++ is bool. By convention. for any other numeric data type zero means "no" and all other values mean "yes" (technically, when converted to bool, zero is converted to false and other values to true, so you can do things like if (a % 2). A function that returns 1 and 2 for yes and no is highly unconventional.
A natural method of checking whether a number is odd is this:
bool isOdd (unsigned long long a)
{
return a % 2;
}
It is somewhat faster than your code (by a factor of about 400 on my computer), gives correct results every time, is readable, and has zero goto statements.
Instead of the if(AVar == 10 || 100 || ..., you can say if(!(AVar % 10)).

Recursive Binary Conversion C++

I am fairly new to C++. I am trying to write a recursive binary function. The binary output needs to be 4 bits, hence the logic around 15 and the binary string length. It converts to binary correctly, the problem I am having is ending the recursive call and returning the binary string to the main function. It seems to just backwards through the call stack? Can someone help me understand what is going on?
Assuming using namespace std. I know this is not good practice, however it is required for my course.
string binary(int number, string b){
if (number > 0 && number < 15){
int temp;
temp = number % 2;
b = to_string(temp) + b;
number = number / 2;
binary(number, b);
}
else if (number > 15){
b = "1111";
number = number - 15;
binary(number, b);
}
else if (number == 15){
b = "11110000";
return b;
}
//should be if number < 1
else{
int s = b.size();
//check to make sure the binary string is 4 bits or more
if (s >= 4){
return b;
}
else{
for (int i = s; i < 4; i++){
b = '0' + b;
}
return b;
}
}
}
You have your function returning a string, but then you require the user to supply an initialized string for you, and you throw away the return value except for the base cases of 15 and 0. The rest of the time, your actual communication is using the parameter b. This multiple communication will cause some headaches.
I also note that you return a properly padded 4-bit number in normal cases; however, you force a return an 8-bit 15 for the exact value 15. Is this part of the assignment specification?
The logic for larger numbers is weird: if the amount is more than 15, you return "1111" appended to the representation for the remainder. For instance, 20 would return as binary(5) followed by "1111", or "1011111", which is decidedly wrong. Even stranger, it appears that any multiple of 15 will return "11110000", since that clause (== 15) overwrites any prior value of b.
I suggest that you analyze and simplify the logic. There should be two cases:
(BASE) If number == 0, return '0'
(RECUR) return ['1' (for odd) else '0'] + binary(number / 2)
You also need a top-level wrapper that checks the string length, padding out to 4 digits if needed. If the "wrapper" logic doesn't fit your design ideas, then drop it, and work only with the b parameter ... but then quit returning values in your other branches, since you don't use them.
Does this get you moving?

Find the length of an integer in C++ [duplicate]

This question already has answers here:
C++ - how to find the length of an integer
(17 answers)
Closed 7 years ago.
In Java, I use
int length = String.valueOf(input).length();
to find the length of an integer.
My question is: Are there any similar ways to do so in C++?
I have already tried the for loops and while loops such as:
while (input > 0){
input/=10;
count++;
So, apart from the loops are there anything else available in C++. Thank you for your answer.
If you want an exact counterpart of what you have written in Java, you can use:
int length = to_string(input).length();
Note that to_string is a C++11 feature. Also, be careful with negative numbers.
The number of digits can be calculated without converting to a string first by using the number's logarithm:
std::size_t intlen(int i) {
if (i == 0) return 1;
else if (i < 0) return 2 + static_cast<std::size_t>(std::log10(-i));
else if (i > 0) return 1 + static_cast<std::size_t>(std::log10(i));
}
The logartihm is only defined for positive numbers, so negatives and zero have to be handled separately, counting the - sign as an additional character. Replace log10 by log2 to obtain the number of binary digits (this is possible for any base).
Note however that converting to strings first (e.g. by using std::to_string) is a locale-dependent operation and can thus yield different results for different language settings - some locales insert a thousands separator (e.g. 100,000) which will not show up using the above formula.
unsigned int number_of_digits = 0;
do {
++number_of_digits;
n /= base; } while (n);
// n is your base number.
Talking about pre-C++11, you can use the same approach, but with sprintf.
Convert integer to a char array, and then get its length:
char buffer[30];
int length = sprintf(buffer, "%d", input);
Here is the working IDEOne example.
Apart from the loops there is recursion. For example, for positive integers you can do:
unsigned int len(unsigned int n)
{
return n ? len(n/10)+1 : 0;
}

C++ - Overloading operator>> and processing input using C-style strings

I'm working on an assignment where we have to create a "MyInt" class that can handle larger numbers than regular ints. We only have to handle non-negative numbers. I need to overload the >> operator for this class, but I'm struggling to do that.
I'm not allowed to #include <string>.
Is there a way to:
a. Accept input as a C-style string
b. Parse through it and check for white space and non-numbers (i.e. if the prompt is cin >> x >> y >> ch, and the user enters 1000 934H, to accept that input as two MyInts and then a char).
I'm assuming it has something to do with peek() and get(), but I'm having trouble figuring out where they come in.
I'd rather not know exactly how to do it! Just point me in the right direction.
Here's my constructor, so you can get an idea for what the class is (I also have a conversion constructor for const char *.
MyInt::MyInt (int n)
{
maxsize = 1;
for (int i = n; i > 9; i /= 10) {
// Divides the number by 10 to find the number of times it is divisible; that is the length
maxsize++;
}
intstring = new int[maxsize];
for (int j = (maxsize - 1); j >= 0; j--) {
// Copies the integer into an integer array by use of the modulus operator
intstring[j] = n % 10;
n = n / 10;
}
}
Thanks! Sorry if this question is vague, I'm still new to this. Let me know if I can provide any more info to make the question clearer.
So what you basically want is to parse a const char* to retrieve a integer number inside it, and ignore all whitespace(+others?) characters.
Remember that characters like '1' or 'M' or even ' ' are just integers, mapped to the ASCII table. So you can easily convert a character from its notation human-readable ('a') to its value in memory. There are plenty of sources on ascii table and chars in C/C++ so i'll let you find it, but you should get the idea. In C/C++, characters are numbers (of type char).
With this, you then know you can perform operations on them, like addition, or comparison.
Last thing when dealing with C-strings : they are null-terminated, meaning that the character '\0' is placed right after their last used character.

Efficient Exponentiation For HUGE Numbers (I'm Talking Googols)

I am in the midst of solving a simple combination problem whose solution is 2^(n-1).
The only problem is 1 <= n <= 2^31 -1 (max value for signed 32 bit integer)
I tried using Java's BigInteger class but It times out for numbers 2^31/10^4 and greater, so that clearly doesn't work out.
Furthermore, I am limited to using only built-in classes for Java or C++.
Knowing I require speed, I chose to build a class in C++ which does arithmetic on strings.
Now, when I do multiplication, my program multiplies similarly to how we multiply on paper for efficiency (as opposed to repeatedly adding the strings).
But even with that in place, I can't multiply 2 by itself 2^31 - 1 times, it is just not efficient enough.
So I started reading texts on the problem and I came to the solution of...
2^n = 2^(n/2) * 2^(n/2) * 2^(n%2) (where / denotes integer division and % denotes modulus)
This means I can solve exponentiation in a logarithmic number of multiplications. But to me, I can't get around how to apply this method to my code? How do I choose a lower bound and what is the most efficient way to keep track of the various numbers that I need for my final multiplication?
If anyone has any knowledge on how to solve this problem, please elaborate (example code is appreciated).
UPDATE
Thanks to everyone for all your help! Clearly this problem is meant to be solved in a realistic way, but I did manage to outperform java.math.BigInteger with a power function that only performs ceil(log2(n)) iterations.
If anyone is interested in the code I've produced, here it is...
using namespace std;
bool m_greater_or_equal (string & a, string & b){ //is a greater than or equal to b?
if (a.length()!=b.length()){
return a.length()>b.length();
}
for (int i = 0;i<a.length();i++){
if (a[i]!=b[i]){
return a[i]>b[i];
}
}
return true;
}
string add (string& a, string& b){
if (!m_greater_or_equal(a,b)) return add(b,a);
string x = string(a.rbegin(),a.rend());
string y = string(b.rbegin(),b.rend());
string result = "";
for (int i = 0;i<x.length()-y.length()+1;i++){
y.push_back('0');
}
int carry = 0;
for (int i =0;i<x.length();i++){
char c = x[i]+y[i]+carry-'0'-'0';
carry = c/10;
c%=10;
result.push_back(c+'0');
}
if (carry==1) result.push_back('1');
return string(result.rbegin(),result.rend());
}
string multiply (string&a, string&b){
string row = b, tmp;
string result = "0";
for (int i = a.length()-1;i>=0;i--){
for (int j= 0;j<(a[i]-'0');j++){
tmp = add(result,row);
result = tmp;
}
row.push_back('0');
}
return result;
}
int counter = 0;
string m_pow (string&a, int exp){
counter++;
if(exp==1){
return a;
}
if (exp==0){
return "1";
}
string p = m_pow(a,exp/2);
string res;
if (exp%2==0){
res = "1"; //a^exp%2 is a^0 = 1
} else {
res = a; //a^exp%2 is a^1 = a
}
string x = multiply(p,p);
return multiply(x,res);
//return multiply(multiply(p,p),res); Doesn't work because multiply(p,p) is not const
}
int main(){
string x ="2";
cout<<m_pow(x,5000)<<endl<<endl;
cout<<counter<<endl;
return 0;
}
As mentioned by #Oli's answer, this is not a question of computing 2^n as that's trivially just a 1 followed by 0s in binary.
But since you want to print them out in decimal, this becomes a question of how to convert from binary to decimal for very large numbers.
My answer to that is that it's not realistic. (I hope this question just stems from curiosity.)
You mention trying to compute 2^(2^31 - 1) and printing that out in decimal. That number is 646,456,993 digits long.
Java BigInteger can't do it. It's meant for small numbers and uses O(n^2) algorithms.
As mentioned in the comments, there are no built-in BigNum libraries in C++.
Even Mathematica can't handle it: General::ovfl : Overflow occurred in computation.
Your best bet is to use the GMP library.
If you're just interested in seeing part of the answer:
2^(2^31 - 1) = 2^2147483647 =
880806525841981676603746574895920 ... 7925005662562914027527972323328
(total: 646,456,993 digits)
This was done using a close-sourced library and took roughly 37 seconds and 3.2 GB of memory on a Core i7 2600K # 4.4 GHz including the time needed to write all 646 million digits to a massive text file.
(It took notepad longer to open the file than needed to compute it.)
Now to answer your question of how to actually compute such a power in the general case, #dasblinkenlight has the answer to that which is a variant of Exponentiation by Squaring.
Converting from binary to decimal for large numbers is a much harder task. The standard algorithm here is Divide-and-Conquer conversion.
I do not recommend you try to implement the latter - as it's far beyond the scope of starting programmers. (and is also somewhat math-intensive)
You don't need to do any multiplication at all. 2^(n-1) is just 1 << (n-1), i.e. 1 followed by (n-1) zeros (in binary).
The easiest way to apply this method in your code is to apply it the most direct way - recursively. It works for any number a, not only for 2, so I wrote code that takes a as a parameter to make it more interesting:
MyBigInt pow(MyBigInt a, int p) {
if (!p) return MyBigInt.One;
MyBigInt halfPower = pow(a, p/2);
MyBigInt res = (p%2 == 0) ? MyBigInt.One : a;
return res * halfPower * halfPower;
}