How to convert large integers to base 2^32? - c++

First off, I'm doing this for myself so please don't suggest "use GMP / xint / bignum" (if it even applies).
I'm looking for a way to convert large integers (say, OVER 9000 digits) into a int32 array of 232 representations. The numbers will start out as base 10 strings.
For example, if I wanted to convert string a = "4294967300" (in base 10), which is just over INT_MAX, to the new base 232 array, it would be int32_t b[] = {1,5}. If int32_t b[] = {3,2485738}, the base 10 number would be 3 * 2^32 + 2485738. Obviously the numbers I'll be working with are beyond the range of even int64 so I can't exactly turn the string into an integer and mod my way to success.
I have a function that does subtraction in base 10. Right now I'm thinking I'll just do subtraction(char* number, "2^32") and count how many times before I get a negative number, but that will probably take a long time for larger numbers.
Can someone suggest a different method of conversion? Thanks.
EDIT
Sorry in case you didn't see the tag, I'm working in C++

Assuming your bignum class already has multiplication and addition, it's fairly simple:
bignum str_to_big(char* str) {
bignum result(0);
while (*str) {
result *= 10;
result += (*str - '0');
str = str + 1;
}
return result;
}
Converting the other way is the same concept, but requires division and modulo
std::string big_to_str(bignum num) {
std::string result;
do {
result.push_back(num%10);
num /= 10;
} while(num > 0);
std::reverse(result.begin(), result.end());
return result;
}
Both of these are for unsigned only.

To convert from base 10 strings to your numbering system, starting with zero continue adding and multiplying each base 10 digit by 10. Every time you have a carry add a new digit to your base 2^32 array.

The simplest (not the most efficient) way to do this is to write two functions, one to multiply a large number by an int, and one to add an int to a large number. If you ignore the complexities introduced by signed numbers, the code looks something like this:
(EDITED to use vector for clarity and to add code for actual question)
void mulbig(vector<uint32_t> &bignum, uint16_t multiplicand)
{
uint32_t carry=0;
for( unsigned i=0; i<bignum.size(); i++ ) {
uint64_t r=((uint64_t)bignum[i] * multiplicand) + carry;
bignum[i]=(uint32_t)(r&0xffffffff);
carry=(uint32_t)(r>>32);
}
if( carry )
bignum.push_back(carry);
}
void addbig(vector<uint32_t> &bignum, uint16_t addend)
{
uint32_t carry=addend;
for( unsigned i=0; carry && i<bignum.size(); i++ ) {
uint64_t r=(uint64_t)bignum[i] + carry;
bignum[i]=(uint32_t)(r&0xffffffff);
carry=(uint32_t)(r>>32);
}
if( carry )
bignum.push_back(carry);
}
Then, implementing atobignum() using those functions is trivial:
void atobignum(const char *str,vector<uint32_t> &bignum)
{
bignum.clear();
bignum.push_back(0);
while( *str ) {
mulbig(bignum,10);
addbig(bignum,*str-'0');
++str;
}
}

I think Docjar: gnu/java/math/MPN.java might contain what you're looking for, specifically the code for public static int set_str (int dest[], byte[] str, int str_len, int base).

Start by converting the number to binary. Starting from the right, each group of 32 bits is a single base2^32 digit.

Related

Custom strtoull functions producing invalid results

I do not have access to anything like strtoull on my actual platform, so I need to find/handroll one. I've tried all four from this answer and they all give me the same, wrong answer, on my windows testing platform. I also tried on online compilers.
One of the functions is
unsigned long long strtoull_simple(const char *s) {
unsigned long long sum = 0;
while (*s) {
sum = sum*10 + (*s++ - '0');
}
return sum;
}
And given "87ddb08343547aec" it produces 9277008343552481 instead of the real value 9790175242790140652 evident here and also evident if you use strtoull where available. Why do all of those functions fail to provide the correct value?
As mentioned in the comments, the code looks like it is for base-10 numbers but the number you are trying to parse looks base-16. You can add a parameter to specify the base:
unsigned long long strtoull_simple(const char *s, int base)
{
unsigned long res = 0;
while (*s) {
// TODO: handle invalid chars
char c = tolower(*s);
res = (res * base) + (isdigit(c) ? c - '0' : c - 'a' + 10);
*s++
}
return res;
}
And call it with
printf("%llu", strtoull_simple("87ddb08343547aec", 16));
Output:
9790175242790140652

Multiply 2 1000-digit binary numbers in C++ [duplicate]

I have the following code
int i, a, z;
i = 2343243443;
a = 5464354324324324;
z = i * a;
cout << z << endl;
When these are multiplied it gives me -1431223188 which is not the answer. How can I make it give me the correct answer?
The result overflows the int (and also std::uint64_t)
You have to use some BigInt library.
As Jarod42 suggested is perfectly okay, but i am not sure whether overflow will take place or not ?
Try to store each and every digit of number in an array and after that multiply. You will definitely get the correct answer.
For more detail how to multiply using array follow this post http://discuss.codechef.com/questions/7349/computing-factorials-of-a-huge-number-in-cc-a-tutorial
Use pan paper approach as we used in 2nd standard.
Store two numbers in two different array in reverse order. And take ans array as size of (arr1.size + arr2.size).And also initilize ans array to zero.
In your case
arr1[10]={3,4,4,3,4,2,3,4,3,2},
arr2[15]={4,2,3,4,2,3,,4,5,3,4,5,3,4,6,4,5};
for(int i=0;i<arr1_length;i++)
{
for(int j=0;j<arr2_length;j++)
{
ans[i+j]+=arr1[i]*arr2[j];
ans[i+j+1]=ans[i+j+1]+ans[i+j]/10;
ans[i+j]%=10;
}
}
Then ans array contain the result.Please print carefully ans array. it may contain leading zero.
ints only hold 32 bits. When the result of a multiplication is larger than 2^31 - 1, the result rolls over to a large negative value. Instead of using the int data type, use long long int, which holds 64 bits.
You should first try to use 64-bit numbers (long or better, unsigned long if everything is positive). With unsigned long you can operate between 0 and 18446744073709551615, with long between -9223372036854775808 and 9223372036854775807.
If it is not enough, then there is no easy solution, you have to perform your operation at software level using arrays of unsigned long for instance, and overload "<<" operator for display. But this is not that easy, and I guess you are a beginner (no offense) considering the question you asked.
If 64-bit representation is not enough for you, I think you should consider floating-point representation, especially "double". With double, you can represent numbers between about -10^308 and 10^308. You won't be able to have perfectly accurate computatiosn on very large number (the least significant digits won't be computed), but this should be a good-enough option for whatever you want to do here.
First, you have to make your value long longs
Second, you would want to add a (long long) in front of the multiplication. This is because when you have (ab) it returns an int therefore if you want it to return a long long you would want (long long)(ab).
I would like to elaborate on, and clarify Shravan Kumar's Answer using a full-fledged code. The code starts with a long integers a & b, which are multiplied using array, converted to a string and then back into the long int.
#include <iostream>
#include <string>
#include<algorithm>
using namespace std;
int main()
{
//Numbers to be multiplied
long a=111,b=100;
//Convert them to strings (or character array)
string arr1 = to_string(a), arr2 = to_string(b);
//Reverse them
reverse(arr1.begin(), arr1.end());
reverse(arr2.begin(), arr2.end());
//Getting size for final result, just to avoid dynamic size
int ans_size = arr1.size() + arr2.size();
//Declaring array to store final result
int ans[ans_size]={0};
//Multiplying
//In a reverse manner, just to avoid reversing strings explicitly
for(int i=0; i<arr1.size();i++)
{
for(int j=0; j<arr2.size();j++)
{
//Convert array elements (char -> int)
int p = (int)(arr1[i]) - '0';
int q = (int)(arr2[j]) - '0';
//Excerpt from Shravan's answer above
ans[i+j]+=p*q;
ans[i+j+1]=ans[i+j+1]+ans[i+j]/10;
ans[i+j]%=10;
}
}
//Declare array to store string form of final answer
string s="";
for(auto i=0;i<ans_size; ++i)
s += to_string(ans[i]);
reverse(s.begin(), s.end() );
//If last element is 0, it should be skipped
if(s[0] =='0')
{
string ss(s,1,s.size()-1);
s=ss;
}
//Final answer
cout<< s;
return 0;
}
Use float instead. It can go up to about 3.4028235 × 1038
// its may heplfull for you
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAX 1000
void reverse(char *from, char *to ){
int len=strlen(from);
int l;
for(l=0;l<len;l++)to[l]=from[len-l-1];
to[len]='\0';
}
void call_mult(char *first,char *sec,char *result){
char F[MAX],S[MAX],temp[MAX];
int f_len,s_len,f,s,r,t_len,hold,res;
f_len=strlen(first);
s_len=strlen(sec);
reverse(first,F);
reverse(sec,S);
t_len=f_len+s_len;
r=-1;
for(f=0;f<=t_len;f++)temp[f]='0';
temp[f]='\0';
for(s=0;s<s_len;s++){
hold=0;
for(f=0;f<f_len;f++){
res=(F[f]-'0')*(S[s]-'0') + hold+(temp[f+s]-'0');
temp[f+s]=res%10+'0';
hold=res/10;
if(f+s>r) r=f+s;
}
while(hold!=0){
res=hold+temp[f+s]-'0';
hold=res/10;
temp[f+s]=res%10+'0';
if(r<f+s) r=f+s;
f++;
}
}
for(;r>0 && temp[r]=='0';r--);
temp[r+1]='\0';
reverse(temp,result);
}
int main(){
char fir[MAX],sec[MAX],res[MAX];
while(scanf("%s%s",&fir,&sec)==2){
call_mult(fir,sec,res);
int len=strlen(res);
for(int i=0;i<len;i++)printf("%c",res[i]);
printf("\n");
}
return 0;
}
You can use queue data structure to find the product of two really big numbers with O(n*m). n and m are the number of digits in a number.

How to convert large number strings into integer in c++?

Suppose, I have a long string number input in c++. and we have to do numeric operations on it. We need to convert this into the integer or any possible way to do operations, what are those?
string s="12131313123123213213123213213211312321321321312321213123213213";
Looks like the numbers you want to handle are way to big for any standard integer type, so just "converting" it won't give you a lot. You have two options:
(Highly recommended!) Use a big integer library like e.g. gmp. Such libraries typically also provide functions for parsing and formatting the big numbers.
Implement your big numbers yourself, you could e.g. use an array of uintmax_t to store them. You will have to implement all sorts of arithmetics you'd possibly need yourself, and this isn't exactly an easy task. For parsing the number, you can use a reversed double dabble implementation. As an example, here's some code I wrote a while ago in C, you can probably use it as-is, but you need to provide some helper functions and you might want to rewrite it using C++ facilities like std::string and replacing the struct used here with a std::vector -- it's just here to document the concept
typedef struct hugeint
{
size_t s; // number of used elements in array e
size_t n; // number of total elements in array e
uintmax_t e[];
} hugeint;
hugeint *hugeint_parse(const char *str)
{
char *buf;
// allocate and initialize:
hugeint *result = hugeint_create();
// this is just a helper function copying all numeric characters
// to a freshly allocated buffer:
size_t bcdsize = copyNum(&buf, str);
if (!bcdsize) return result;
size_t scanstart = 0;
size_t n = 0;
size_t i;
uintmax_t mask = 1;
for (i = 0; i < bcdsize; ++i) buf[i] -= '0';
while (scanstart < bcdsize)
{
if (buf[bcdsize - 1] & 1) result->e[n] |= mask;
mask <<= 1;
if (!mask)
{
mask = 1;
// this function increases the storage size of the flexible array member:
if (++n == result->n) result = hugeint_scale(result, result->n + 1);
}
for (i = bcdsize - 1; i > scanstart; --i)
{
buf[i] >>= 1;
if (buf[i-1] & 1) buf[i] |= 8;
}
buf[scanstart] >>= 1;
while (scanstart < bcdsize && !buf[scanstart]) ++scanstart;
for (i = scanstart; i < bcdsize; ++i)
{
if (buf[i] > 7) buf[i] -= 3;
}
}
free(buf);
return result;
}
Your best best would be to use a large numbers computational library.
One of the best out there is the GNU Multiple Precision Arithmetic Library
Example of a useful function to solve your problem::
Function: int mpz_set_str (mpz_t rop, const char *str, int base)
Set the value of rop from str, a null-terminated C string in base
base. White space is allowed in the string, and is simply ignored.
The base may vary from 2 to 62, or if base is 0, then the leading
characters are used: 0x and 0X for hexadecimal, 0b and 0B for binary,
0 for octal, or decimal otherwise.
For bases up to 36, case is ignored; upper-case and lower-case letters
have the same value. For bases 37 to 62, upper-case letter represent
the usual 10..35 while lower-case letter represent 36..61.
This function returns 0 if the entire string is a valid number in base
base. Otherwise it returns -1.
Documentation: https://gmplib.org/manual/Assigning-Integers.html#Assigning-Integers
If string contains number which is less than std::numeric_limits<uint64_t>::max(), then std::stoull() is the best opinion.
unsigned long long = std::stoull(s);
C++11 and later.

How can I multiply really big numbers c++

I have the following code
int i, a, z;
i = 2343243443;
a = 5464354324324324;
z = i * a;
cout << z << endl;
When these are multiplied it gives me -1431223188 which is not the answer. How can I make it give me the correct answer?
The result overflows the int (and also std::uint64_t)
You have to use some BigInt library.
As Jarod42 suggested is perfectly okay, but i am not sure whether overflow will take place or not ?
Try to store each and every digit of number in an array and after that multiply. You will definitely get the correct answer.
For more detail how to multiply using array follow this post http://discuss.codechef.com/questions/7349/computing-factorials-of-a-huge-number-in-cc-a-tutorial
Use pan paper approach as we used in 2nd standard.
Store two numbers in two different array in reverse order. And take ans array as size of (arr1.size + arr2.size).And also initilize ans array to zero.
In your case
arr1[10]={3,4,4,3,4,2,3,4,3,2},
arr2[15]={4,2,3,4,2,3,,4,5,3,4,5,3,4,6,4,5};
for(int i=0;i<arr1_length;i++)
{
for(int j=0;j<arr2_length;j++)
{
ans[i+j]+=arr1[i]*arr2[j];
ans[i+j+1]=ans[i+j+1]+ans[i+j]/10;
ans[i+j]%=10;
}
}
Then ans array contain the result.Please print carefully ans array. it may contain leading zero.
ints only hold 32 bits. When the result of a multiplication is larger than 2^31 - 1, the result rolls over to a large negative value. Instead of using the int data type, use long long int, which holds 64 bits.
You should first try to use 64-bit numbers (long or better, unsigned long if everything is positive). With unsigned long you can operate between 0 and 18446744073709551615, with long between -9223372036854775808 and 9223372036854775807.
If it is not enough, then there is no easy solution, you have to perform your operation at software level using arrays of unsigned long for instance, and overload "<<" operator for display. But this is not that easy, and I guess you are a beginner (no offense) considering the question you asked.
If 64-bit representation is not enough for you, I think you should consider floating-point representation, especially "double". With double, you can represent numbers between about -10^308 and 10^308. You won't be able to have perfectly accurate computatiosn on very large number (the least significant digits won't be computed), but this should be a good-enough option for whatever you want to do here.
First, you have to make your value long longs
Second, you would want to add a (long long) in front of the multiplication. This is because when you have (ab) it returns an int therefore if you want it to return a long long you would want (long long)(ab).
I would like to elaborate on, and clarify Shravan Kumar's Answer using a full-fledged code. The code starts with a long integers a & b, which are multiplied using array, converted to a string and then back into the long int.
#include <iostream>
#include <string>
#include<algorithm>
using namespace std;
int main()
{
//Numbers to be multiplied
long a=111,b=100;
//Convert them to strings (or character array)
string arr1 = to_string(a), arr2 = to_string(b);
//Reverse them
reverse(arr1.begin(), arr1.end());
reverse(arr2.begin(), arr2.end());
//Getting size for final result, just to avoid dynamic size
int ans_size = arr1.size() + arr2.size();
//Declaring array to store final result
int ans[ans_size]={0};
//Multiplying
//In a reverse manner, just to avoid reversing strings explicitly
for(int i=0; i<arr1.size();i++)
{
for(int j=0; j<arr2.size();j++)
{
//Convert array elements (char -> int)
int p = (int)(arr1[i]) - '0';
int q = (int)(arr2[j]) - '0';
//Excerpt from Shravan's answer above
ans[i+j]+=p*q;
ans[i+j+1]=ans[i+j+1]+ans[i+j]/10;
ans[i+j]%=10;
}
}
//Declare array to store string form of final answer
string s="";
for(auto i=0;i<ans_size; ++i)
s += to_string(ans[i]);
reverse(s.begin(), s.end() );
//If last element is 0, it should be skipped
if(s[0] =='0')
{
string ss(s,1,s.size()-1);
s=ss;
}
//Final answer
cout<< s;
return 0;
}
Use float instead. It can go up to about 3.4028235 × 1038
// its may heplfull for you
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAX 1000
void reverse(char *from, char *to ){
int len=strlen(from);
int l;
for(l=0;l<len;l++)to[l]=from[len-l-1];
to[len]='\0';
}
void call_mult(char *first,char *sec,char *result){
char F[MAX],S[MAX],temp[MAX];
int f_len,s_len,f,s,r,t_len,hold,res;
f_len=strlen(first);
s_len=strlen(sec);
reverse(first,F);
reverse(sec,S);
t_len=f_len+s_len;
r=-1;
for(f=0;f<=t_len;f++)temp[f]='0';
temp[f]='\0';
for(s=0;s<s_len;s++){
hold=0;
for(f=0;f<f_len;f++){
res=(F[f]-'0')*(S[s]-'0') + hold+(temp[f+s]-'0');
temp[f+s]=res%10+'0';
hold=res/10;
if(f+s>r) r=f+s;
}
while(hold!=0){
res=hold+temp[f+s]-'0';
hold=res/10;
temp[f+s]=res%10+'0';
if(r<f+s) r=f+s;
f++;
}
}
for(;r>0 && temp[r]=='0';r--);
temp[r+1]='\0';
reverse(temp,result);
}
int main(){
char fir[MAX],sec[MAX],res[MAX];
while(scanf("%s%s",&fir,&sec)==2){
call_mult(fir,sec,res);
int len=strlen(res);
for(int i=0;i<len;i++)printf("%c",res[i]);
printf("\n");
}
return 0;
}
You can use queue data structure to find the product of two really big numbers with O(n*m). n and m are the number of digits in a number.

Shortest way to calculate difference between two numbers?

I'm about to do this in C++ but I have had to do it in several languages, it's a fairly common and simple problem, and this is the last time. I've had enough of coding it as I do, I'm sure there must be a better method, so I'm posting here before I write out the same long winded method in yet another language;
Consider the (lilies!) following code;
// I want the difference between these two values as a positive integer
int x = 7
int y = 3
int diff;
// This means you have to find the largest number first
// before making the subtract, to keep the answer positive
if (x>y) {
diff = (x-y);
} else if (y>x) {
diff = (y-x);
} else if (x==y) {
diff = 0;
}
This may sound petty but that seems like a lot to me, just to get the difference between two numbers. Is this in fact a completely reasonable way of doing things and I'm being unnecessarily pedantic, or is my spidey sense tingling with good reason?
Just get the absolute value of the difference:
#include <cstdlib>
int diff = std::abs(x-y);
Using the std::abs() function is one clear way to do this, as others here have suggested.
But perhaps you are interested in succinctly writing this function without library calls.
In that case
diff = x > y ? x - y : y - x;
is a short way.
In your comments, you suggested that you are interested in speed. In that case, you may be interested in ways of performing this operation that do not require branching. This link describes some.
#include <cstdlib>
int main()
{
int x = 7;
int y = 3;
int diff = std::abs(x-y);
}
All the existing answers will overflow on extreme inputs, giving undefined behaviour. #craq pointed this out in a comment.
If you know that your values will fall within a narrow range, it may be fine to do as the other answers suggest, but to handle extreme inputs (i.e. to robustly handle any possible input values), you cannot simply subtract the values then apply the std::abs function. As craq rightly pointed out, the subtraction may overflow, causing undefined behaviour (consider INT_MIN - 1), and the std::abs call may also cause undefined behaviour (consider std::abs(INT_MIN)). It's no better to determine the min and max of the pair and to then perform the subtraction.
More generally, a signed int is unable to represent the maximum difference between two signed int values. The unsigned int type should be used for the output value.
I see 3 solutions. I've used the explicitly-sized integer types from stdint.h here, to close the door on uncertainties like whether long and int are the same size and range.
Solution 1. The low-level way.
// I'm unsure if it matters whether our target platform uses 2's complement,
// due to the way signed-to-unsigned conversions are defined in C and C++:
// > the value is converted by repeatedly adding or subtracting
// > one more than the maximum value that can be represented
// > in the new type until the value is in the range of the new type
uint32_t difference_int32(int32_t i, int32_t j) {
static_assert(
(-(int64_t)INT32_MIN) == (int64_t)INT32_MAX + 1,
"Unexpected numerical limits. This code assumes two's complement."
);
// Map the signed values across to the number-line of uint32_t.
// Preserves the greater-than relation, such that an input of INT32_MIN
// is mapped to 0, and an input of 0 is mapped to near the middle
// of the uint32_t number-line.
// Leverages the wrap-around behaviour of unsigned integer types.
// It would be more intuitive to set the offset to (uint32_t)(-1 * INT32_MIN)
// but that multiplication overflows the signed integer type,
// causing undefined behaviour. We get the right effect subtracting from zero.
const uint32_t offset = (uint32_t)0 - (uint32_t)(INT32_MIN);
const uint32_t i_u = (uint32_t)i + offset;
const uint32_t j_u = (uint32_t)j + offset;
const uint32_t ret = (i_u > j_u) ? (i_u - j_u) : (j_u - i_u);
return ret;
}
I tried a variation on this using bit-twiddling cleverness taken from https://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax but modern code-generators seem to generate worse code with this variation. (I've removed the static_assert and the comments.)
uint32_t difference_int32(int32_t i, int32_t j) {
const uint32_t offset = (uint32_t)0 - (uint32_t)(INT32_MIN);
const uint32_t i_u = (uint32_t)i + offset;
const uint32_t j_u = (uint32_t)j + offset;
// Surprisingly it helps code-gen in MSVC 2019 to manually factor-out
// the common subexpression. (Even with optimisation /O2)
const uint32_t t = (i_u ^ j_u) & -(i_u < j_u);
const uint32_t min = j_u ^ t; // min(i_u, j_u)
const uint32_t max = i_u ^ t; // max(i_u, j_u)
const uint32_t ret = max - min;
return ret;
}
Solution 2. The easy way. Avoid overflow by doing the work using a wider signed integer type. This approach can't be used if the input signed integer type is the largest signed integer type available.
uint32_t difference_int32(int32_t i, int32_t j) {
return (uint32_t)std::abs((int64_t)i - (int64_t)j);
}
Solution 3. The laborious way. Use flow-control to work through the different cases. Likely to be less efficient.
uint32_t difference_int32(int32_t i, int32_t j)
{ // This static assert should pass even on 1's complement.
// It's just about impossible that int32_t could ever be capable of representing
// *more* values than can uint32_t.
// Recall that in 2's complement it's the same number, but in 1's complement,
// uint32_t can represent one more value than can int32_t.
static_assert( // Must use int64_t to subtract negative number from INT32_MAX
((int64_t)INT32_MAX - (int64_t)INT32_MIN) <= (int64_t)UINT32_MAX,
"Unexpected numerical limits. Unable to represent greatest possible difference."
);
uint32_t ret;
if (i == j) {
ret = 0;
} else {
if (j > i) { // Swap them so that i > j
const int32_t i_orig = i;
i = j;
j = i_orig;
} // We may now safely assume i > j
uint32_t magnitude_of_greater; // The magnitude, i.e. abs()
bool greater_is_negative; // Zero is of course non-negative
uint32_t magnitude_of_lesser;
bool lesser_is_negative;
if (i >= 0) {
magnitude_of_greater = i;
greater_is_negative = false;
} else { // Here we know 'lesser' is also negative, but we'll keep it simple
// magnitude_of_greater = -i; // DANGEROUS, overflows if i == INT32_MIN.
magnitude_of_greater = (uint32_t)0 - (uint32_t)i;
greater_is_negative = true;
}
if (j >= 0) {
magnitude_of_lesser = j;
lesser_is_negative = false;
} else {
// magnitude_of_lesser = -j; // DANGEROUS, overflows if i == INT32_MIN.
magnitude_of_lesser = (uint32_t)0 - (uint32_t)j;
lesser_is_negative = true;
}
// Finally compute the difference between lesser and greater
if (!greater_is_negative && !lesser_is_negative) {
ret = magnitude_of_greater - magnitude_of_lesser;
} else if (greater_is_negative && lesser_is_negative) {
ret = magnitude_of_lesser - magnitude_of_greater;
} else { // One negative, one non-negative. Difference is sum of the magnitudes.
// This will never overflow.
ret = magnitude_of_lesser + magnitude_of_greater;
}
}
return ret;
}
Well it depends on what you mean by shortest. The fastet runtime, the fastest compilation, the least amount of lines, the least amount of memory. I'll assume you mean runtime.
#include <algorithm> // std::max/min
int diff = std::max(x,y)-std::min(x,y);
This does two comparisons and one operation (this one is unavoidable but could be optimized through certain bitwise operations with specific cases, compiler might actually do this for you though). Also if the compiler is smart enough it could do only one comparison and save the result for the other comparison. E.g if X>Y then you know from the first comparison that Y < X but I'm not sure if compilers take advantage of this.