Adding two strings arithmetically - c++

I'm trying to implement a function to add two overly large (let's say 1000 digit long) numbers stored in strings. I'm having problems with correct conversions so I can add numbers correctly.
So far, this is what I've done:
string addBegin (string low, string high, int diff)
{
for (int i = 0; i <= diff; i++)
low = "0" + low;
high = "0" + high;
cout << "low: " << low << "\nhigh: " << high << endl;
string result;
int sum, carry = 0;
for (int i = low.length()-1; i >= 0; i--)
{
sum = (int)low[i] + (int)high[i] + carry;
carry = 0;
if (sum > 9)
{
sum -= 10;
carry = 1;
}
result = to_string(sum) + result;
}
return result;
}
string add (string a, string b)
{
int diff = a.length() - b.length();
if (diff <= 0) return addBegin(a, b, abs(diff));
else return addBegin(b, a, diff);
}
int main (void)
{
string x = add("52","205");
cout << "result: " << x << endl;
return 0;
}
Output:
low: 0052
high: 0205 //the first zero is for potential carry
result: 87899293 //wrong, should be 0257
The result here is made of 4 numbers: 87, 89, 92 and 93. That is obviously wrong, I did some unwanted additions with ASCII values. Any ideas how to make this work? Or is there, by any chance, some ridiculously simple way to add two veeeeery long numbers?

sum = (int)low[i] + (int)high[i] + carry;
This adds the values of the character encodings in e.g. ASCII. You want to subtract '0' from the encoding to get the numeric value.
sum = low[i] - '0' + high[i] - '0' + carry;

Do not forget subtracting '0' from low[i] and high[i] when doing the math.
(int)low[i] is 0x30..0x39 for chars '0'..'9'.

A problem is that you use
sum = (int)low[i] + (int)high[i] + carry;
which should be
sum = low[i] - '0' + high[i] - '0' + carry;

Related

How to cyclically increment and decrement 26 latin characters in a loop

I want to increment or decrement characters, but have them cycle back to a when going beyond z and to z when going before a.
For example incrementing 'w' by 2 gives 'y' and decrementing 'w' by 2 gives 'u'.
Another example decrementing 'w' by 28 gives 'u' and decrementing 'a' by 256 gives 'e'.
I've figure out how to increment: char(int(A[i]+B-97)%26 +97) where B is the shift amount and A[i] is current character.
Don't overcomplicate. Use modulo to keep the increment or decrement amount in a range of 26 characters, then simply do a range check:
char cyclicIncrementDecrement(char ch, int amount)
{
int newValue = int(ch) + (amount % 26);
if (newValue < 'a') newValue += 26;
if (newValue > 'z') newValue -= 26;
return char(newValue);
}
This method of course assumes ch already is in range of 'a' to 'z'. If not, you need to handle that (put it in range or throw an exception or whatever is appropriate for your application).
Running this:
int main()
{
std::cout << cyclicIncrementDecrement('w', -2) << std::endl;
std::cout << cyclicIncrementDecrement('w', 2) << std::endl;
std::cout << cyclicIncrementDecrement('w', -28) << std::endl;
std::cout << cyclicIncrementDecrement('a', -256) << std::endl;
std::cout << cyclicIncrementDecrement('z', -256) << std::endl;
std::cout << cyclicIncrementDecrement('z', -51) << std::endl;
std::cout << cyclicIncrementDecrement('z', -52) << std::endl;
}
gives:
u
y
u
e
d
a
z
Using modular arithmetic, calculate your answer as modulo 26 and then add 'a' (ASCII 97) to your result.
char cyclic_increment(char ch, int n) {
int tmp = ((ch - 97) + n) % 26;
if (tmp < 0 )
tmp += 26;
return (char)(tmp + 97);
}
Alternatively, you could write the above (without an if) as:
char cyclic_increment(char ch, int n) {
return (((ch - 'a') + n) % 26 + 26) % 26 + 'a';
}
This handles both positive and negative offsets:
unsigned char az_cyclic(int in_ch)
{
constexpr int mod = 26; // There are 26 letters in the English alphabet
int offset = (in_ch - 'a') % mod; // (ASCII To zero-based offset) Mod_26 remainder
if (offset < 0) // If negative offset,
offset += mod; // normalize to positive. For example: -1 to 25
return 'a' + offset; // Normalize to ASCII
}
Use-cases:
int main()
{
unsigned char out_ch = '\0';
out_ch = az_cyclic('a' - 1); // 'z'
out_ch = az_cyclic('a' - 1 - 26); // 'z'
out_ch = az_cyclic('a' - 2); // 'y'
out_ch = az_cyclic('a' + 4); // 'e'
out_ch = az_cyclic('a' + 4 + 26); // 'e'
out_ch = az_cyclic('a' + 2); // 'c'
return 0;
}

Hexadecimal Calculator for Addition and Subtraction

I have an issue with my program which is used to calculate addition and subtraction for Hexadecimals. The algorithm of my program is:
Take 2 strings inputted by the user, and "+" or "-" depending on the
operator they chose
Convert the 2 strings into decimals, and add or subtract
If the second number is bigger, use the bigger number to subtract the smaller number, and put a "-" in front of it when returning the result
(1 - 8 should = -7, but instead, I take 8 - 1 = 7, and return "-" and "7" so it gives "-7)
Take the decimal result from the operation and convert back to hexadecimal
Return string of hexadecimal
However, I have run into a issue where my calculations give me wrong answers.
(For e.g FFFFFF + FFFFFFFFFF prints "FFFFFFE" instead of "10000FFFFFE")
What can I do to solve the issue?
I created my own Power function for this program as I need a a number that can go up to 16 Fs for the Hexadecimal string.
Power Function:
unsigned long long int result = 1;
int i;
for (i = 0; i < y; i++)
{
result *= x;
}
return result;
Code:
int i;
int power = FirstHexaNumber.length() - 1;
int power2 = SeconHexaNumber.length() - 1;
int checkLength = FirstHexaNumber.length();
int checkLength2 = SeconHexaNumber.length();
unsigned long long int decimalNumber = 0;
unsigned long long int decimalNumber2 = 0;
unsigned long long int totalDecimal;
int temporary;
string result;
if (Operator == '+') //check if operator is add or minus
{
//Convert Hex to Decimal for first number
for (i = 0; i < checkLength; i++)
{
if (int(FirstHexaNumber[i]) >= 48 && int(FirstHexaNumber[i]) <= 57) { // check if FirstHexaNumber 0 to 9
decimalNumber += ((int(FirstHexaNumber[i])) - 48) * powerFunc(16, power); //formula to convert hexadecimal into decimal, int(FirstHexaNumber[i]) is used to convert hexa into a number
}
else if (int(FirstHexaNumber[i]) >= 65 && int(FirstHexaNumber[i]) <= 70) // check if FirstHexaNumber is A to F
{
decimalNumber += ((int(FirstHexaNumber[i])) - 55)*powerFunc(16, power);
}
else if (int(FirstHexaNumber[i]) >= 97 && int(FirstHexaNumber[i]) <= 102) // check if FirstHexaNumber is a to f
{
int x = powerFunc(16, power);
decimalNumber += ((int(FirstHexaNumber[i])) - 87)* x;
}
power--; //power-- since it starts from "HexaNumber.length - 1". Power should decrease as assignment of power goes down
}
//Convert Hex to Decimal for second number
for (i = 0; i < checkLength2; i++)
{
if (int(SeconHexaNumber[i]) >= 48 && int(SeconHexaNumber[i]) <= 57) {
decimalNumber2 += ((int(SeconHexaNumber[i])) - 48) * powerFunc(16, power2); //formula to convert Hexadecimal to Decimal
}
else if (int(SeconHexaNumber[i]) >= 65 && int(SeconHexaNumber[i]) <= 70)
{
decimalNumber2 += ((int(SeconHexaNumber[i])) - 55)*powerFunc(16, power2); //formula to convert Hexadecimal to Decimal
}
else if (int(SeconHexaNumber[i]) >= 97 && int(SeconHexaNumber[i]) <= 102)
{
unsigned long long int x = powerFunc(16, power2);
decimalNumber2 += ((int(SeconHexaNumber[i])) - 87)*x; //formula to convert Hexadecimal to Decimal
}
power2--;
}
totalDecimal = decimalNumber + decimalNumber2; //Adds the total decimal to convert into hexadecimal
if (totalDecimal == 0)
{
return "0";
}
//Converts Decimal to Hexadecimal
for (i = 0; totalDecimal != 0; i++) //as long as totalDecimal does not hit 0 from being divided by 16, run the loop
{
temporary = totalDecimal % 16; //use temporary as a variable to temporarily hold onto the number remainder of mod 16
if (temporary >= 10) //if temporary >= 10, that means it needs to be converted to alphabet
{
result.insert(0, 1, temporary + 55); //result.insert inserts a string of text into a spot, and pushes everything else backwards.
} //in this case, result.insert assigns "temporary+55" into the spot of characters 0 to 1.
else //else, it means that the decimal will be a number, add 48 to convert to ascii
{
result.insert(0, 1, temporary + 48);
}
totalDecimal = totalDecimal / 16; //divide by 16 to move on to finding the next digit/alphabet
}
return result;
}
else if (Operator == '-') //check if operator is add or minus
{
//Convert Hex to Decimal for first number
for (i = 0; i < checkLength; i++) //as long as the loop does not exceed the length of the hexadecimal, run it
{
if (int(FirstHexaNumber[i]) >= 48 && int(FirstHexaNumber[i]) <= 57) {
decimalNumber += ((int(FirstHexaNumber[i])) - 48) * powerFunc(16, power);
}
else if (int(FirstHexaNumber[i]) >= 65 && int(FirstHexaNumber[i]) <= 70)
{
decimalNumber += ((int(FirstHexaNumber[i])) - 55)*powerFunc(16, power);
}
else if (int(FirstHexaNumber[i]) >= 97 && int(FirstHexaNumber[i]) <= 102)
{
decimalNumber += ((int(FirstHexaNumber[i])) - 87)*powerFunc(16, power);
}
power--;
}
//Convert Hex to Decimal for second number
for (i = 0; i < checkLength2; i++)
{
if (int(SeconHexaNumber[i]) >= 48 && int(SeconHexaNumber[i]) <= 57) {
decimalNumber2 += ((int(SeconHexaNumber[i])) - 48) * powerFunc(16, power2);
}
else if (int(SeconHexaNumber[i]) >= 65 && int(SeconHexaNumber[i]) <= 70)
{
decimalNumber2 += ((int(SeconHexaNumber[i])) - 55)*powerFunc(16, power2);
}
else if (int(SeconHexaNumber[i]) >= 97 && int(SeconHexaNumber[i]) <= 102)
{
decimalNumber2 += ((int(SeconHexaNumber[i])) - 87)*powerFunc(16, power2);
}
power2--;
}
if (decimalNumber >= decimalNumber2)
{
totalDecimal = decimalNumber - decimalNumber2; //subtract bigger number by smaller number.
if (totalDecimal == 0)
{
return "0";
}
for (i = 0; totalDecimal != 0; i++)
{
temporary = totalDecimal % 16;
if (temporary >= 10)
{
result.insert(0, 1, temporary + 55);
}
else
{
result.insert(0, 1, temporary + 48);
}
totalDecimal = totalDecimal / 16;
}
return result;
}
else
{
totalDecimal = decimalNumber2 - decimalNumber; //subtract bigger number by smaller number.
if (totalDecimal == 0)
{
return "0";
}
for (i = 0; totalDecimal != 0; i++)
{
temporary = totalDecimal % 16;
if (temporary >= 10)
{
result.insert(0, 1, temporary + 55);
}
else
{
result.insert(0, 1, temporary + 48);
}
totalDecimal = totalDecimal / 16;
}
return "-" + result;
}
}
return 0;
You can try this snippet:
int a,b;
cout << "\nEnter A in hex: ";
cin >> hex >> a;
cout << "\nEnter B in hex: ";
cin >> hex >> b;
cout << "\n Addition of " << hex << a <<" and "<< hex << b << " is " << hex << a+b;
cout << "\n Substraction of " << hex << a << " and " << hex << b << " is " << hex << a - b;
int x = powerFunc(16, power); should be long long x = powerFunc(16, power);
Don't know full source of the function pow, the return type should be long long too.
Hexadecimal Calculator can be more simple.
#include <sstream>
std::stringstream ss1(s1),ss2(s2);
ss1 >> std::hex >> i1;
ss2 >> std::hex >> s2;
std::cout << std::hex << std::uppercase << i1 + s2 << std::endl;
std::stringstream res;
res << std::hex << std::uppercase << i1 + i2;
return res.str();

Converting Binary to Integer in C++ returns weird results

I'm trying to create a simple program to convert a binary number, for example 111100010 to decimal 482. I've done the same in Python, and it works, but I can't find what I'm doing wrong in C++.
When I execute the C++ program, I get -320505788. What have I done wrong?
This is the Python code:
def digit_count(bit_number):
found = False
count = 0
while not found:
division = bit_number / (10 ** count)
if division < 1:
found = True
else:
count += 1
return count
def bin_to_number(bit_number):
digits = digit_count(bit_number)
number = 0
for i in range(digits):
exp = 10 ** i
if exp < 10:
digit = int(bit_number % 10)
digit = digit * (2 ** i)
number += digit
else:
digit = int(bit_number / exp % 10)
digit = digit * (2 ** i)
number += digit
print(number)
return number
bin_to_convert = 111100010
bin_to_number(bin_to_convert)
# returns 482
This is the C++ code:
#include <iostream>
#include <cmath>
using namespace std;
int int_length(int bin_number);
int bin_to_int(int bin_number);
int main()
{
cout << bin_to_int(111100010) << endl;
return 0;
}
int int_length(int bin_number){
bool found = false;
int digit_count = 0;
while(!found){
int division = bin_number / pow(10, digit_count);
if(division < 1){
found = true;
}
else{
digit_count++;
}
}
return digit_count;
}
int bin_to_int(int bin_number){
int number_length = int_length(bin_number);
int number = 0;
for(int i = 0; i < number_length; i++){
int e = pow(10, i);
int digit;
if(e < 10){
digit = bin_number % 10;
digit = digit * pow(2, i);
number = number + digit;
}
else{
if((e % 10) == 0){
digit = 0;
}
else{
digit = bin_number / (e % 10);
}
digit = digit * pow(2, i);
number = number + digit;
}
}
return number;
}
The problem is that you converted this fragment of Python code
else:
digit = int(bit_number / exp % 10)
digit = digit * (2 ** i)
number += digit
into this:
else{
if((e % 10) == 0){
digit = 0;
}
else{
digit = bin_number / (e % 10);
}
digit = digit * pow(2, i);
number = number + digit;
}
In other words, you are trying to apply / after applying %, and protect from division by zero in the process.
This is incorrect: you should apply them the other way around, like this:
else{
digit = (bit_number / e) % 10;
digit = digit * pow(2, i);
number = number + digit;
}
Demo 1
Note that the entire conditional is redundant - you can remove it from your for loop:
for(int i = 0; i < number_length; i++){
int e = pow(10, i);
int digit = (bit_number / e) % 10;
digit = digit * pow(2, i);
number = number + digit;
}
Demo 2
One problem is that the 111100010 in main is not a binary literal for 482 base 10 but is actually the decimal value of 111100010. If you are going to use a binary literal there is no need for any of your code, just write it out since an integer is an integer regardless of the representation.
If you are trying to process a binary string, you could do something like this instead
#include <iostream>
#include <algorithm>
using namespace std;
int bin_to_int(const std::string& binary_string);
int main()
{
cout << bin_to_int("111100010") << endl;
cout << 0b111100010 << endl;
return 0;
}
int bin_to_int(const std::string& bin_string){
//Strings index from the left but bits start from the right so reverse it
std::string binary = bin_string;
std::reverse(binary.begin(), binary.end());
int number_length = bin_string.size();
//cout << "bits " << number_length << "\n";
int number = 0;
for(int i = 0; i <= number_length; i++){
int bit_value = 1 << i;
if(binary[i] == '1')
{
//cout << "Adding " << bit_value << "\n";
number += bit_value;
}
}
return number;
}
Note that to use the binary literal you will need to compile for c++14.

Function return value (char and integer)

I have a function that supposed to compute sum and return integer result, but it doesn't return the right value because when I multiply by 2 it takes value from ASCII table, not the integer value.
This part of the code is correct:
sum += *(ptrISBN + i) - '0'
, but when i try to multiply it by 2 it gives me ANSCII output, can someone help me to convert it into integer value somehow?
int checkSum(char *ptrISBN)
{
int sum = 0;
for (int i = 0; i < 14; i++) {
if (isdigit(*(ptrISBN + i)))
sum += *(ptrISBN + i) - '0' * 2;
}
return sum;
}
Try:
int checkSum(char *ptrISBN)
{
int sum = 0;
for (int i = 0; i < 14; i++) {
if (isdigit(*(ptrISBN + i)))
sum += (*(ptrISBN + i) - '0') * 2; //little change here
}
return sum;
}
I assume You wanted to convert character ('0' to '9') to its int value and then multiply it by 2.
Without change You were doing sum += *(ptrISBN + i) - ('0' * 2); which is not what You were looking for. That happened because multiplication was done before subtraction.

subtraction of binary numbers in a linked list c++

Hi new to posting but a long time follower. I have been working on a project for quite sometime now and i can not for the life of me figure out how to implement the subtraction operator of two binary numbers in a linked list. The program will take in an integer and convert it to binary then add, subtract, and multiply the binary numbers then return the result.
So i have the addition operator done, (this works fine just wanted to show how i was doing my main cpp.)
addition
Binary operator+(const Binary &b1, const Binary &b2){
Binary newBinary = Binary();
unsigned iMax = b1.get_degree();
if (iMax < b2.get_degree()){
iMax = b2.get_degree();
}
//carry bit
unsigned bCarry = 0;
//traverse the list for each bit b1 and b2, highest degree
for (unsigned i = 0; i <= iMax; ++i){
unsigned sum = b1.get_bit(i) + b2.get_bit(i) + bCarry;
//determine if there is new carry
if (sum >= 2){
bCarry = 1;
sum -= 2;
}
else bCarry = 0;
if (1 == sum){
newBinary.set_bit(1, i);
}
}
//handle extra carry bit
if (1 == bCarry){
newBinary.set_bit(1, iMax + 1);
return newBinary;
}
}
addition works fine and i tried to take what addition does and apply it to the subtraction operator but i keep on hitting a wall lol
subtraction:
Binary operator-(const Binary &b1, const Binary &b2){
Binary newBinary = Binary();
unsigned iMax = b1.get_degree();
Binary switchNode = Binary();
int cutoffBit = b1.get_degree();
if (iMax < b2.get_degree()){
iMax = b2.get_degree();
}
//swtich the bits of b2 by switching them from 0 to 1 and from 1 to 0
//then add 1 to b2
for (unsigned i = 0; i < cutoffBit; i++){
if (b2.get_bit(i) == 0){
switchNode.set_bit(1, i);
}
else if (b2.get_bit(i) == 1){
switchNode.set_bit(0, i-1);
}
}
cout << switchNode; cout << "\t switchNode";
cout << "\n";
cout << b2; cout<< "\t b2";
unsigned bCarry = 0;
//sub the two binary numbers.
for (unsigned i = 0; i <= iMax; ++i){
unsigned sub = b1.get_bit(i) + b2.get_bit(i);
if (sub >= 0){
bCarry = 0;
sub -= 1;
}
else bCarry = 1;
if (1 == sub){
switchNode.set_bit(1, i);
}
}
//handles the drop bit
if (1 == bCarry){
switchNode.set_bit(1, iMax - 1);
return switchNode - 1;
}
cout << "\n";
cout << switchNode; cout << "\t switch node";
i was trying to do some debugging with my couts so that why those are there.. so any help in pointing me in the right direction will be greatly appreciated!
-Jason
Your 2's complement code ("flip the bits and add 1") does not appear to do what it claims to do. For example, if bit 0 is a 1, it will try to set bit -1!