Store a long double in several double variables - c++

I have to store a long double variable in JSON format. JSON supports double variables but not long double. Then I have to split the long double value in several double values, but I don't know how to do that easily.
I already did that for long long int variables by this way :
std::vector<long int> long_long_int__to__long_int(long long int x)
{
std::vector<long int> split;
const unsigned long int n = sizeof(long long int) / sizeof(long int);
for(unsigned long int i = 1; i < n; ++i)
{
split.push_back((long int)(x % (long long int)std::numeric_limits<long int>::max));
x /= (long long int)std::numeric_limits<long int>::max;
}
split.push_back(x);
return split;
}
Any idea how to do that with floating points variables ?

Here is the solution I can think of, and it's applicable to your long long int problem as well.
consider any type you want to store as a array of hex values, whether it's a long long int or long double.
choose one Binary-to-text encoding algorithm and use it to convert the array to a readable string.
store the string to JSON

Store two doubles: (double)x and (double)(x - (double)x). (And pay attention to compilers bugs and switches affecting the handling of precision, they may cause issues when using such techniques, a gcc bug for instance).

Related

C++ calculation of long long with int

below you can find a part of my C++ code of a box class.
When I want to calculate the volume for
l=1039
b=3749
h=8473
I am expecting 33004122803.
Unfortunately I do not understand why only the first implementation (CalculateVolume1) gives the correct answer.
The other two calculations result in -1355615565.
Can someone please help me to understand why this is the case?
class Box{
private:
int l,b,h;
public:
//works
long long CalculateVolume1() { return (long long) l*b*h;}
// does not work
long long CalculateVolume2() { return long long v = l*b*h;}
//does not work
long long CalculateVolume3()
{
long long v = long long (l)* long long(b)* long long (h);
return v;
}
};
In the first one, (long long) l*b*h, the cast applies to l, as if it had been written ((long long)l)*b*h. So l gets converted to long long. And since one of the factors in the multiplication is long long, the other two are promoted to long long and the result of the multiplication is correct.
"Fixing" the syntactic errors in the second and third,
long long v = l*b*h;
here, the type of all three factors is int, so the multiplication is done on ints, and the result overflows.
long long v = (long long)l*(long long)b*(long long)h;
this is essentially the same as the first: all three factors are promoted to long long, this time by explicit casts on all three, so the result is calculated using long long arithmetic, and the result fits.
The problem with the second one as written is that you can't define a variable inside a return statement. So
return long long v = l; // illegal
should be:
long long v = l;
return v;
The problem with the third one as written is that a function-style cast has to have a name that's a single word:
long long v = int(l); // okay, but pointless
long long v = long long(l); // error, invalid name
could be:
typedef long long my_type;
long long v = my_type(l); // okay

Why number is getting out of long long range in C++?

Given two non-negative integers num1 and num2 represented as string, return the sum of num1 and num2.
class Solution {
public:
vector<int> addToArrayForm(vector<int>& A, int K) {
int i=A.size()-1;
vector<int> result={};
long long int no=0;
for(int x:A)
{
no=no+x*pow(10,i);
i--;
}
no=no+K;
if(no==0)
return {0};
while(no>0)
{
long long int r=no%10;
result.push_back(r);
no=no/10;
}
reverse(result.begin(),result.end());
return result;
}
};
I am getting this error with long long.
Line 9: Char 14: runtime error: 1e+19 is outside the range of representable values of type 'long long' (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:18:14
Provided that long long is implemented by a signed 64-bit integer, 1e19 is indeed out of the positive range of that type. The maximum representable value of that type would be 9223372036854775807.
As to whether 1e19 is a possible value, it is because it depends on the size of the vector A that you pass as input. You may want to limit your algorithm to only accept A of up to a certain size by adding a check against std::numeric_limits<long long>::digits10.
maybe initialise std::vector<long long int> result will solve your problem. Because you defined it as an integer, but you pusing back long long variable.
or you can use static_cast<type> to convert types temprorary for ongoing alegorithm (cppref: static_cast)
disclaimer: I answered, because I can't comment (I don't have 50 rep)

Why does implicit conversion of int to long long int give unexpected answer in C++?

I read that conversion from int to long long int is promotion and hence thought that there shouldn't be any issue as there is no loss of data, unlike the vice versa conversion.
But when I multiply two ints of large value and store it in long long int, it is showing me negative number.
Eg:
int a=1000000, b=1000000;
long long int c=a*b;
cout<<c;
The above code gives me a negative value. Can someone explain why?
a*b is still of type int. Once it's evaluated, the result is then converted to long long int. At that point it's too late to avoid overflow. Convert one of your values to long long int before preforming the multiplication. Try this :
#include <iostream>
int main()
{
int a = 1000000, b = 1000000;
long long int c = static_cast<long long int>(a)*b;
std::cout << c;
return 0;
};
The multiplication is happening as an int, which overflows, giving Undefined Behaviour (in this case overflow, which is very normal - your combination of compiler+settings may even guarantee it), and after that the result is being converted to long long.
I think you want to do the conversion on one of the arguments before multiplication, so that the multiplication is performed using long longs:
long long c = static_cast<long long>(a)*b;
In this way, b will be promoted to long long before the multiplication takes place, and the whole operation will be performed safely, and with the desired result.
Because multiplying two ints will result in another int that comes with all the overflow problems attached. This int is then (after the fact) promoted to a long long int which still means it's not what you want.
Promote at least one of the operands to have the other promoted and get the result you want.

How to represent large number in c++

I am trying to represent some large numbers in c++. In the below code if tried only to print s the compiler would not complain. But If try to make some multiplications and storing it in t the compiler would say integer overflow in expression...
I tried to make it unsigned long long t but again the compiler complains. Is there any way in doing this multiplication without having any overflow?
int main ()
{
long long int s = 320718425168;
long long int t = 4684688*68461; //4684688*68461 = 320718425168
return 0;
}
The literals used as the factors of the products are of type int, which cannot represent the product.
Cast one of the factors to long long first.
long long t = (long long)4684688 * 68461;
Or use the corresponding literal suffix ll or LL to change the literals type. I.e.
long long t = 4684688LL * 68461;
Demo.

Which data type to use for a very large numbers in C++?

I have to store the number 600851475143 in my program. I tried to store it in long long int variable and long double as well but on compiling it shows the error
integer constant is too large for "long" type.
I have also tried unsigned long long int too. I am using MinGW 5.1.6 for running g++ on windows.
What datatype should I use to store the number?
long long is fine, but you have to use a suffix on the literal.
long long x = 600851475143ll; // can use LL instead if you prefer.
If you leave the ll off the end of the literal, then the compiler assumes that you want it to be an int, which in most cases is a 32-bit signed number. 32-bits aren't enough to store that large value, hence the warning. By adding the ll, you signify to the compiler that the literal should be interpreted as a long long, which is big enough to store the value.
The suffix is also useful for specifying which overload to call for a function. For example:
void foo(long long x) {}
void foo(int x) {}
int main()
{
foo(0); // calls foo(int x)
foo(0LL); // calls foo(long long x)
}
You had the right idea with long long int (or unsigned long long int), but to prevent the warning, you need to tell the compiler that the constant is a long long int:
long long int value = 600851475143LL;
Those "L"s can be lower-case, but I'd advise against it -- depending on the font, a lower-case "L" often looks a lot like a one digit ("1") instead.
Have a look at the GNU MP Bignum library http://gmplib.org/