I have an issue with my program which is used to calculate addition and subtraction for Hexadecimals. The algorithm of my program is:
However, I have run into a issue where my calculations give me wrong answers. (For eg 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 aa 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();
According to a magical wizard (well uh, programmer ) like me, this magical function shall grant your wish:-
Note: The source code(s) not copied from any sources.
std::tuple<std::vector<std::string>, std::vector<char>> DistributeHexStringToStrings(std::string Target)
{
std::string::size_type n1 = 0;
while ((n1 = Target.find(std::string(" "), n1)) != std::string::npos)
{
Target.replace(n1, std::string(" ").size(), "");
n1 += std::string("").size();
}
if (Target.find("--") != std::string::npos || Target.find("++") != std::string::npos ||
Target.find("-+") != std::string::npos || Target.find("+-") != std::string::npos)
throw std::invalid_argument("You should not use double signs!");
std::string::size_type n2 = 0;
while ((n2 = Target.find(std::string("-"), n2)) != std::string::npos)
{
Target.replace(n2, std::string("-").size(), "+-");
n2 += std::string("+-").size();
}
std::vector<char> TermOperator;
if (Target[0] != '+' && Target[1] != '-')
TermOperator.emplace_back('+');
for (auto i = 0; i < signed(Target.size()); i++)
if (Target[i] == '+' && Target[i + 1] != '-')
TermOperator.emplace_back('+');
else if (Target[i] == '+' && Target[i + 1] == '-')
TermOperator.emplace_back('-');
else if (!(Target[i] >= '0' && Target[i] <= '9' || Target[i] >= 'A' && Target[i] <= 'F' ||
Target[i] >= 'a' && Target[i] <= 'f' || Target[i] == '+' || Target[i] == '-'))
throw std::invalid_argument("The specified hexadecimal expression is not valid!");
const size_t Terms = std::count(Target.begin(), Target.end(), '+') + 1;
std::stringstream HexStream(Target);
std::vector<std::string> HexStrings;
for (auto i = 0; i < signed(Terms); i++)
{
std::string Temporary;
std::getline(HexStream, Temporary, '+');
if (Temporary.empty() || Temporary == "-" || Temporary == "+")
continue;
HexStrings.emplace_back(Temporary);
}
return std::make_tuple(HexStrings, TermOperator);
}
This function will distribute the strings in the cleanest possible way. But the work is still undone, we need to use this function properly to get our desired result, and what I have here is another function that can do the conversion of the hex strings to real hex numbers:-
std::vector<long long> ConvertHexaDecimalToDecimal(std::vector<std::string> HexStrings)
{
std::vector<long long> HexValues;
for (auto &elem : HexStrings)
{
if (elem[0] == '-')
elem.erase(elem.begin());
int Temporary;
std::stringstream HexConverter(elem);
HexConverter >> std::hex >> Temporary;
if (Temporary == 0)
continue;
HexValues.emplace_back(Temporary);
}
return HexValues;
}
This function will convert all the hexadecimal string values to real decimal equivalents of the hex numbers, now we need to calculate it like this:-
long long CalculateHexadecimalExpression(std::vector<long long> &HexValues, std::vector<char> &Operators)
{
if (Operators.size() != HexValues.size())
throw std::invalid_argument("Operators and Number of Hex Values do not match!");
long long Result = 0;
for (auto i = 0; i < signed(Operators.size() & HexValues.size()); i++)
{
switch (Operators[i])
{
case '+':
Result += HexValues[i];
break;
case '-':
Result -= HexValues[i];
break;
default: break;
}
}
return Result;
}
This function will do all the resulting calculations for you.
Now you can use these three functions together to yield the desired result you wanted.
Example:-
int main()
{
const std::string Example = "3 + 2";
std::vector<std::string> HStrings;
std::vector<char> HOperators;
std::tie(HStrings, HOperators) = DistributeHexStringToStrings(Example);
auto HNumbers = ConvertHexaDecimalToDecimal(HStrings);
std::cout << ConvertDecimalToHexaDecimalValue(CalculateHexadecimalExpression(HNumbers, HOperators)) << std::endl;
}
Output:-
3855
Note: If you want, you could go one step further and convert the resulting number to a hex too (using this function):-
std::string ConvertDecimalToHexaDecimalValue(const long long Hex, bool UpperCase = true)
{
std::stringstream HexResultStream;
HexResultStream << (Hex < 0 ? "-" : "") << (UpperCase ? std::uppercase : std::nouppercase) << std::hex << abs(Hex);
return HexResultStream.str();
}
And use it like this, ConvertDecimalToHexaDecimalValue(CalculateHexadecimalExpression(HNumbers, HOperators))
.
Which will give you F0F , assign a value to the second parameter as false to yield the hexadecimal string in lowercase. ( eg, ConvertDecimalToHexaDecimalValue(CalculateHexadecimalExpression(HNumbers, HOperators,
false
));
Don't forget to add these includes to the top:-
#include <iostream>
#include <vector>
#include <sstream>
#include <tuple>
Regards from a fellow programmer,
Ruks
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.