Mathematical operations between two strings [duplicate] - c++

This question already has an answer here:
What variable type for extremely big integer numbers?
(1 answer)
Closed 4 years ago.
I'm trying to add subtract and multiply numbers with huge decimals C++.
Example:
4125487821547.87879845215584844588 - 354556689.899455132265468
What I figured so far is that I need to save inputs as a string, but not sure how to proceed after that.
Appreciate the help in advance
Thanks

You need a big integer class or library. There are several implementations available, just to give you an overview on how to use such an external dependency, here is a solution based on Boost:
#include <boost/multiprecision/cpp_int.hpp>
using BigInt = boost::multiprecision::cpp_int;
You can now construct instances by passing string or integral literals to the constructor and do all standard arithmetic operations with these objects, e.g.
const BigInt i("8787984521558484092344588");
const BigInt j("32308942039402934");
std::cout << i - j << "\n";
One nice detail of such classes is that they usually demonstrate one of the few justified scenarios for non-explicit constructors with one argument, i.e., for the sake of smooth interoperability with builtin integral types. Example:
int n = 42;
// Use builtin ints like BigInts via implicit BigInt(int) ctor:
std::cout << (i + n)/(j % 3) << "\n";
You only need the Boost headers for these snippets, no linkage is required. Check out the docs when proceeding with this library.

Related

What does this sentence mean in 'Programming: Principles and Practice Using C++'? [duplicate]

This question already has answers here:
Comparing double to an int
(2 answers)
Closed 2 years ago.
I am reading Programming: Principles and Practice Using C++ and encountered this sentence on page 79 about safe conversions:
In §3.4, we saw that we couldn’t directly add chars or compare a
double to an int.
I think we can compare like this, and it runs successfully
int a = 2;
double b = 3.5;
if (a > b)
{
cout << "No";
}
else
{
cout << "Yes";
}
Did I misunderstand the sentence?
I'll assume you have a 64-bits platform, with 64 bits ints.
int i = 1152921504606846976;
double d = 1152921504606846976.1;
bool b = i < d;
Then, it's not so clear anymore. Your double might have less precision than ints, at some range. The comparison above is unsafe, even though 3 > 3.5 might not be.
Just guessing, since the question is fundamentally about some text that isn't shown, but that statement is correct if you emphasize directly. When you add two char variables both get promoted to int, so you're not directly adding them, and the type of the result is not char. Similarly, comparing values of two different types requires promoting one of the values, so you aren't directly comparing them.
Whether or not such things are "safe" depends on what you mean by "safe".

Using Intel MKL to convert real time domain data to complex frequency and phase data and the inverse as well

I'm writing an audio plugin and I would like to convert a series of real numbers representing sample values into a complex array representing frequency and phase. Then I want to be able to do the opposite, turning a complex array of frequency and phases to a series of real numbers, reconstructing the original data.
I'm using Intel MKL and I see only the possibility to perform real->real conversions or complex->complex conversions. Here's the reference I'm using: Intel MKL FFT Functions.
In that reference, there are two overloaded functions: DftiComputeForward and DftiComputeBackward. So, I would like to use these to do the conversions. In the reference for DftiCreateDescriptor, the only options available for DFTI_FORWARD_DOMAIN are DFTI_COMPLEX and DFTI_REAL, but no option for mixed conversions.
Edit
I found that the phase is actually equal to atan(imaginary/real). I don't want to mislead anyone getting information from questions.
Edit
I just learned that it's best to use atan2(imaginary,real). More information is in the comments.
Every real number is a complex number: ℝ ⊂ ℤ. So going forward from float or double in time domain to complex is trivial. The language does that for you!
#include <complex>
#include <iostream>
int main() {
double d = 42.0;
std::complex<double> z = d;
std::cout << d << " = " << z << '\n';
}
Output: 42 = (42,0)
And the C++ standard library also does everything else. It's quite simple, in fact. For once, the library does pretty much what it says on the box.
Even better: std::complex offers array access. You can reinterpret-cast std::complex<T> to T[2], whether through a reference or a pointer. And thus, std::complex can be "stripped" of its identity and passed into any lower-level API that requires pairs of floats or pairs of doubles.
The complex frequency domain data can be converted to magnitude and phase, and back, as follows:
#include <complex>
#include <iostream>
int main() {
std::complex<double> z{0.7071, 0.7071};
double magnitude = abs(z);
double phase = arg(z); // in radians
std::cout << z << " ≈ (" << magnitude << "∠" << phase*180.0/M_PI << "°)\n";
std::complex<double> z2 = std::polar(magnitude, phase);
std::cout << " ≈ " << z2 << '\n';
}
Output:
(0.7071,0.7071) ≈ (0.99999∠45°)
≈ (0.7071,0.7071)
Once you get the "real" data back, it's not likely that the imaginary part of the time domain data will be zero - it depends on what processing you'll do with the frequency domain data. What you want to convert back is the magnitude of each complex time sample, using the abs function.
There's stuff in the C++ library that's mind-bogglingly overcomplicated, to the point where you have to have the reference open or you won't remember how to use it. See e.g. the mess known as the random number support. Ugh. But complex number support is relatively sane and even follows the notation used in teaching complex number arithmetic :)

Replacing every multiplication with a custom instruction

I have some basic C++ code (included below). I want to be able to replace every multiplication that occurs (including within the cos function included in math.h) with a custom instruction. I am able to directly call the custom instruction within my main, but the 'cos' will still use the old multiplication instruction.
I have considered doing operator overloading, but I was unable to make this function properly.
#include <iostream>
#include <string>
#include <math.h>
int main()
{
int a = 2;
int b = 5;
std::cout << "mult: " << a * b << std::endl;
std::cout << "cos: " << cos(b) << std::endl;
return 0;
}
What is the best way to approach implementing this custom instruction in the way I would like?
There is a way to substitute some functionalities without touching your code. It depends, off course, on how you're building your code.
Assuming that you're using Linux you can inject features using LD_PRELOAD.
Here is a nice explanation on how to do that:
https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/
If that does not apply exactly to your case, you can grab some ideas or simply learn this cool feature.
std::cos provides overloads only for the built-in floating point types float, double, long double (any integral type also can be provided, but it's cast to double internally). You cannot overload operators for built-in types. This means that you can't do what you are asking.
The best you can get is to write your own numeric class that overloads the multiplication operator and write your own trigonometric functions for it using your alternative multiplication implementation.

parsing integer in exponential notation from string

Apparently std::stoi does not accept strings representing integers in exponential notation, like "1e3" (= 1000). Is there an easy way to parse such a string into an integer? One would think that since this notation works in C++ source code, the standard library has a way to parse this.
You can use stod (see docs) to do this, by parsing it as a double first. Be wary of precision issues when casting back though...
#include <iostream> // std::cout
#include <string> // std::string, std::stod
int main () {
std::string text ("1e3");
std::string::size_type sz; // alias of size_t
double result = std::stod(text,&sz);
std::cout << "The result is " << (int)result << std::endl; // outputs 1000
return 0;
}
One would think that since this notation works in C++ source code, the standard library has a way to parse this.
The library and the compiler are unrelated. The reason this syntax works in C++ is that the language allows you to assign expressions of type double to integer variables:
int n = 1E3;
assigns a double expression (i.e. a numeric literal of type double) to an integer variable.
Knowing what's going on here you should be able to easily identify the function in the Standard C++ Library that does what you need.
You can read it as a double using standard streams, for example
double d;
std::cin >> d; //will read scientific notation properly
and then cast it to an int, but obviously double can represent far more values than int, so be careful about that.
Emitting exponential notation into std::stoi would overflow too often and integer overflow in C++ is undefined behaviour.
You need to build your own where you can taylor the edge cases to your specific requirements.
I'd be inclined not to go along the std::stod route since a cast from a double to int is undefined behaviour if the integral part of the double cannot be represented by the int.

What's a need for union { } in C++? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C/C++: When would anyone use a union? Is it basically a remnant from the C only days?
Hi all.
What are the reasons for unions to exist in C++? And what are they, actually?
I found this code:
#include <iostream>
using namespace std;
union mixture {
short number;
char symbol[2];
main() {
mixture m1, m2;
cout << "Enter 2 symbols to form short number made of them: ";
cin >> m1.symbol[0] >> m1.symbol[1];
cout << "2 more to go..: ";
cin >> m2.symbol[0] >> m2.symbol[1];
cout.setf(ios::hex);
cout << "Biggest received number: " << (m1.number > m2.number ? m1.number : m2.number) << endl;
system("pause");
return 0;
}
return 0;
But actually, what I win from using union { struct1, struct2 } instead of writing struct { struct2(struct1}: a(struct1.a), b(_struct1.b {}} struct2? to transparently support both types?
I do some embedding stuff (Arduino etc), but never seen the real usage for structs.
Examples, please.
The union lets you treat your data as either char or short without having to cast. Casting pointer between types can produce type-punning errors in the optimizer and generate incorrect output.
EDIT: For an example, I use unions to byte swap doubles and floats after reading them from a file. If you read byteswapped floating point numbers the numbers might get normalized or adjusted while bytes swapped, which of course results in junk once they're swapped:
union float_int
{
float ff;
int32_t ii;
};
float_int data;
read(fd, &data, 4); // Read 4 bytes
byteswap(data.ii); // Passing as a float can alter the bits.
float myvalue = data.ff; // My float is now byteswaped and ready to go.
A union is fundamentally different from a struct in that only one of the members is guaranteed to be usable at a time -- but this is a white lie, see next. (The data may or may not overlap depending upon the compiler, target, and various packing rules and this overlap can be [ab]used in cases The overlap can be [ab]used depending upon compiler, target, types, etc).
Conceptually a union represents a "discrete value" (X has/is A or B but X is not/does not have A and B) and it also allows the compiler (or whatever uses this model) to represent the data more efficiently in cases.
Happy coding.
In hardware level code you have to be sure your bits are in consecutive memory, this is one way to make sure of it.
edit: You dont HAVE to be sure, but there are plenty of cases it does.
Firstly, they're inherited from C and there was no good reason to remove support, so C++ retained support.
It's one of the only widely-supported ways to do type-punning (but still likely illegal by the letter of the standard).
It can save space in certain cases.