Im trying to make a binary converter, the problem however is that when I build it, it usually decrypts my test number "101" which should be 5 into something along the lines of 300 - 3000.
int main()
{
char a;
string bintered;
int bincrypted = 0, bincrypter;
cout<<"Would you like to try the binary to decimal converter? Y/N"<<endl;
cin>>a;
if (a == 'Y' || a == 'y')
{
cout<<"Ok, enter a binary number and we will decrypt it > ";
cin>>bintered;
int x = bintered.length() - 1; //multiplier counting down
int y = 0;
int power = 0;
while (x != -1)
{
power = bintered[y] * pow(2.0, x);
bincrypted = bincrypted + power;
y++;
x = x - 1;
}
cout<<"Final answer is: "<<bincrypted<<endl;
}
return 0;
}
When I tried doing cout<<bintered[y] * pow(2.0, x); it gave me 196, 96 and 49 for the three loops it did.
Am i using the pow function incorrectly or what?
bintered[y] returns the ascii code of the character, so 48 for 0 and 49 for 1.
Related
I am trying to solve a problem regarding power of two integers. The problem description is like below:
Given a positive integer which fits in a 32 bit signed integer, find
if it can be expressed as A^P where P > 1 and A > 0. A and P both
should be integers.
Example:
Input: n = 8
Output: true
8 can be expressed as 2^3
Input: n = 49
Output: true
49 can be expressed as 7^2
Now, I have followed below approach to solve the problem.
int Solution::isPower(int A) {
if(A == 1)
{
return true;
}
for(int x = 2; x <= sqrt(A); x++)
{
unsigned long long product = x * x;
while(product <= A && product > 0)
{
if(product == A)
{
return true;
}
product = product * x;
}
}
return false;
}
But, I have found another solution from geeksforgeeks which is using just log divisions to find out whether the value can be expressed in power of two integers.
bool isPower(int a)
{
if (a == 1)
return true;
for (int i = 2; i * i <= a; i++) {
double val = log(a) / log(i);
if ((val - (int)val) < 0.00000001)
return true;
}
return false;
}
Can anyone please explain me the above logarithmic solution? Thanks in advance.
It's using maths to solve this.
9=3^2
Log 9 = log 3^2... Adding log at both side
Log 9 = 2 * log 3...using log property
2 = log 9 / log 3
As you can see the last statement is equivalent to code
double val = log(a) / log(i);
Then it's checking Val - round(val) is 0...if that's true val is the ans otherwise it won't be 0. Logarithms don't give precise ans.
I wanted to convert a string to an integer, and I find the "454" was converted to 453.
I have defined a function which can convert an integer-string to an integer. But when I tested it, I found the "454" was converted to 453. I tried another number 565, and it is correct.
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int strtonum(string num){
int i = 0;
int n = 0;
int result=0;
for(i = num.length()-1; i>=0; i--,n++){
if(num[i] == '-'){
result-=2*result;
break;
}
cout<<result<<" + "<<(num[i] - '0')*pow(10,n);
result += (num[i] - '0')*pow(10,n);
cout<<" = "<<result<<endl;
}
return result;
}
int main()
{
string x;
cin>>x;
cout<<strtonum(x)<<endl;
return 0;
}
Result
454
0 + 4 = 4
4 + 50 = 54
54 + 400 = 453
453
Process returned 0 (0x0) execution time : 2.763 s
Press any key to continue.
565
0 + 5 = 5
5 + 60 = 65
65 + 500 = 565
565
Process returned 0 (0x0) execution time : 3.314 s
Press any key to continue.
Your approach involves floating-point computations through your use of the std::pow function.
As you may know, floating-point computations can introduce error. I'm a little surprised to see that here with good wholesome whole numbers, but still you're not dealing with it at all before truncating back to int.
I suggest a different, integer-only manner of raising to a power of ten (perhaps a nice loop!).
Also, as bruno pointed out, this:
result-=2*result;
is overflow-prone and unnecessary when you can just do this instead:
result = -result;
or:
result *= -1;
The usual approach to this is to accumulate values with multiplication by 10:
int convert(std::string text) {
bool negative = false;
int cur = 0;
if (text[cur] == '-') {
negative = true;
++cur;
}
int value = 0;
while (cur < text.length()) {
value *= 10;
value += text[cur++] - '0';
}
if (negative)
value = -value;
return value;
}
Note: this code has not been tested. It might contain errors.
To generate a UFI number, I use a bitset of size 74. To perform step 2 of UFI generation, I need to convert this number:
9 444 732 987 799 592 368 290
(10000000000000000000000000000101000001000001010000011101011111100010100010)
into:
DFSTTM62QN6DTV1
by converting the first representation to base 31 and getting the equivalent chars from a table.
#define PAYLOAD_SIZE 74
// payload = binary of 9444732987799592368290
std::bitset<PAYLOAD_SIZE> bs_payload(payload);
/*
perform modulo 31 to obtain:
12(D), 14(F), 24(S), 25(T), 25, 19, 6, 2, 22, 20, 6, 12, 25, 27, 1
*/
Is there a way to perform the conversion on my bitset without using an external BigInteger library?
Edit: I finally done a BigInteger class even if the Cheers and hth. - Alf's solution works like a charm
To get modulo 31 of a number you just need to sum up the digits in base 32, just like how you calculate modulo 3 and 9 of a decimal number
unsigned mod31(std::bitset<74> b) {
unsigned mod = 0;
while (!b.none()) {
mod += (b & std::bitset<74>(0x1F)).to_ulong();
b >>= 5;
}
while (mod > 31)
mod = (mod >> 5) + (mod & 0x1F);
return mod;
}
You can speedup the modulo calculation by running the additions in parallel like how its done here. The similar technique can be used to calculate modulo 3, 5, 7, 15... and 231 - 1
C - Algorithm for Bitwise operation on Modulus for number of not a power of 2
Is there any easy way to do modulus of 2^32 - 1 operation?
Logic to check the number is divisible by 3 or not?
However since the question is actually about base conversion and not about modulo as the title said, you need to do a real division for this purpose. Notice 1/b is 0.(1) in base b + 1, we have
1/31 = 0.000010000100001000010000100001...32 = 0.(00001)32
and then N/31 can be calculated like this
N/31 = N×2-5 + N×2-10 + N×2-15 + ...
uint128_t result = 0;
while (x)
{
x >>= 5;
result += x;
}
Since both modulo and division use shift-by-5, you can also do both them together in a single loop.
However the tricky part here is how to round the quotient properly. The above method will work for most values except some between a multiple of 31 and the next power of 2. I've found the way to correct the result for values up to a few thousands but yet to find a generic way for all values
You can see the same shift-and-add method being used to divide by 10 and by 3. There are more examples in the famous Hacker's Delight with proper rounding. I didn't have enough time to read through the book to understand how they implement the result correction part so maybe I'll get back to this later. If anyone has any idea to do that it'll be grateful.
One suggestion is to do the division in fixed-point. Just shift the value left so that we have enough fractional part to round later
uint128_t result = 0;
const unsigned num_fraction = 125 - 75 // 125 and 75 are the nearest multiple of 5
// or maybe 128 - 74 will also work
uint128_t x = UFI_Number << num_fraction;
while (x)
{
x >>= 5;
result += x;
}
// shift the result back and add the fractional bit to round
result = (result >> num_fraction) + ((result >> (num_fraction - 1)) & 1)
Note that your result above is incorrect. I've confirmed the result is CEOPPJ62MK6CPR1 from both Yaniv Shaked's answer and Wolfram alpha unless you use different symbols for the digits
This code seems to work. To guarantee the result I think you need to do additional testing. E.g. first with small numbers where you can compute the result directly.
Edit: Oh, now I noticed you posted the required result digits, and they match. Means it's generally good, but still not tested for corner cases.
#include <assert.h>
#include <algorithm> // std::reverse
#include <bitset>
#include <vector>
#include <iostream>
using namespace std;
template< class Type > using ref_ = Type&;
namespace base31
{
void mul2( ref_<vector<int>> digits )
{
int carry = 0;
for( ref_<int> d : digits )
{
const int local_sum = 2*d + carry;
d = local_sum % 31;
carry = local_sum / 31;
}
if( carry != 0 )
{
digits.push_back( carry );
}
}
void add1( ref_<vector<int>> digits )
{
int carry = 1;
for( ref_<int> d : digits )
{
const int local_sum = d + carry;
d = local_sum % 31;
carry = local_sum / 31;
}
if( carry != 0 )
{
digits.push_back( carry );
}
}
void divmod2( ref_<vector<int>> digits, ref_<int> mod )
{
int carry = 0;
for( int i = int( digits.size() ) - 1; i >= 0; --i )
{
ref_<int> d = digits[i];
const int divisor = d + 31*carry;
carry = divisor % 2;
d = divisor/2;
}
mod = carry;
if( digits.size() > 0 and digits.back() == 0 )
{
digits.resize( digits.size() - 1 );
}
}
}
int main() {
bitset<74> bits(
"10000000000000000000000000000101000001000001010000011101011111100010100010"
);
vector<int> reversed_binary;
for( const char ch : bits.to_string() ) { reversed_binary.push_back( ch - '0' ); }
vector<int> base31;
for( const int bit : reversed_binary )
{
base31::mul2( base31 );
if( bit != 0 )
{
base31::add1( base31 );
}
}
{ // Check the conversion to base31 by converting back to base 2, roundtrip:
vector<int> temp31 = base31;
int mod;
vector<int> base2;
while( temp31.size() > 0 )
{
base31::divmod2( temp31, mod );
base2.push_back( mod );
}
reverse( base2.begin(), base2.end() );
cout << "Original : " << bits.to_string() << endl;
cout << "Reconstituted: ";
string s;
for( const int bit : base2 ) { s += bit + '0'; cout << bit; }; cout << endl;
assert( s == bits.to_string() );
}
cout << "Base 31 digits (msd to lsd order): ";
for( int i = int( base31.size() ) - 1; i >= 0; --i )
{
cout << base31[i] << ' ';
}
cout << endl;
cout << "Mod 31 = " << base31[0] << endl;
}
Results with MinGW g++:
Original : 10000000000000000000000000000101000001000001010000011101011111100010100010
Reconstituted: 10000000000000000000000000000101000001000001010000011101011111100010100010
Base 31 digits (msd to lsd order): 12 14 24 25 25 19 6 2 22 20 6 12 25 27 1
Mod 31 = 1
I did not compile the psuedo code, but you can get the generate understanding of how to convert the number:
// Array for conversion of value to base-31 characters:
char base31Characters[] =
{
'0',
'1',
'2',
...
'X',
'Y'
};
void printUFINumber(__int128_t number)
{
string result = "";
while (number != 0)
{
var mod = number % 31;
result = base31Characters[mod] + result;
number = number / 31;
}
cout << number;
}
I'm trying to solve problem 8 from project euler but I'm getting way too big numbers as results and I don't know why.
The problem is "Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?"
My code :
#include <iostream>
#include <string>
int main()
{
std::string str = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
long long a = 1;
long long fin = 0;
for (int c = 0; c < 988; c++)
{
for (int d = 0; d < 13; d++)
{
a = a * str.at(c + d);
}
if (a > fin)
{
fin = a;
std::cout << fin << " at " << c << std::endl;
}
a = 1;
}
system("pause");
}
The output :
7948587103611909356 at 0
8818137127266647872 at 15
8977826317031653376 at 71
9191378290313403392 at 214
9205903071867879424 at 573
Press any key to continue...
The problem is that the characters '0' through '9' are not the same as the integers 0 through 9; rather, '0' has the value 48, '1' has the value 49, and so on. (These are the ASCII values of those characters.)
So to convert from a digit character to the desired number — for example, to extract e.g. 3 from '3' — you need to subtract '0'. In other words, you need to change this:
a = a * str.at(c + d);
to this:
a = a * (str.at(c + d) - '0');
I'm working on a program that will allow me to multiply/divide/add/subtract binary numbers together. In my program I'm making all integers be represented as vectors of digits.
I've managed to figure out how to do this with addition, however multiplication has got me stumbled and I was wondering if anyone could give me some advice on how to get the pseudo code as a guide for this program.
Thanks in advance!
EDIT: I'm trying to figure out how to create the algorithm for multiplication still to clear things up. Any help on how to figure this algorithm would be appreciated. I usually don't work with C++, so it takes me a bit longer to figure things out with it.
You could also consider the Booth's algorithm if you'd like to multiply:
Booth's multiplication algorithm
Long multiplication in pseudocode would look something like:
vector<digit> x;
vector<digit> y;
total = 0;
multiplier = 1;
for i = x->last -> x->first //start off with the least significant digit of x
total = total + i * y * multiplier
multiplier *= 10;
return total
you could try simulating a binary multiplier or any other circuit that is used in a CPU.
Just tried something, and this would work if you only multiply unsigned values in binary:
unsigned int multiply(unsigned int left, unsigned int right)
{
unsigned long long result = 0; //64 bit result
unsigned int R = right; //32 bit right input
unsigned int M = left; //32 bit left input
while (R > 0)
{
if (R & 1)
{// if Least significant bit exists
result += M; //add by shifted left
}
R >>= 1;
M <<= 1; //next bit
}
/*-- if you want to check for multiplication overflow: --
if ((result >> 32) != 0)
{//if has more than 32 bits
return -1; //multiplication overflow
}*/
return (unsigned int)result;
}
However, that's at the binary level of it... I just you have vector of digits as input
I made this algorithm that uses a binary addition function that I found on the web in combination with some code that first adjusts "shifts" the numbers before sending them to be added together.
It works with the logic that's in this video https://www.youtube.com/watch?v=umqLvHYeGiI
and this is the code:
#include <iostream>
#include <string>
using namespace std;
// This function adds two binary strings and return
// result as a third string
string addBinary(string a, string b)
{
string result = ""; // Initialize result
int s = 0; // Initialize digit sum
int flag =0;
// Traverse both strings starting from last
// characters
int i = a.size() - 1, j = b.size() - 1;
while (i >= 0 || j >= 0 || s == 1)
{
// Computing the sum of the digits from right to left
//x = (condition) ? (value_if_true) : (value_if_false);
//add the fire bit of each string to digit sum
s += ((i >= 0) ? a[i] - '0' : 0);
s += ((j >= 0) ? b[j] - '0' : 0);
// If current digit sum is 1 or 3, add 1 to result
//Other wise it will be written as a zero 2%2 + 0 = 0
//and it will be added to the heading of the string (to the left)
result = char(s % 2 + '0') + result;
// Compute carry
//Not using double so we get either 1 or 0 as a result
s /= 2;
// Move to next digits (more to the left)
i--; j--;
}
return result;
}
int main()
{
string a, b, result= "0"; //Multiplier, multiplicand, and result
string temp="0"; //Our buffer
int shifter = 0; //Shifting counter
puts("Enter you binary values");
cout << "Multiplicand = ";
cin >> a;
cout<<endl;
cout << "Multiplier = ";
cin >> b;
cout << endl;
//Set a pointer that looks at the multiplier from the bit on the most right
int j = b.size() - 1;
// Loop through the whole string and see if theres any 1's
while (j >= 0)
{
if (b[j] == '1')
{
//Reassigns the original value every loop to delete the old shifting
temp = a;
//We shift by adding zeros to the string of bits
//If it is not the first iteration it wont add any thing because we did not "shift" yet
temp.append(shifter, '0');
//Add the shifter buffer bits to the result variable
result = addBinary(result, temp);
}
//we shifted one place
++shifter;
//move to the next bit on the left
j--;
}
cout << "Result = " << result << endl;
return 0;
}