int a{5},b{2},c{9};
double d = (double)a / (double)b + (double)c;
Or I can use static_cast. Either way is verbose, especially when the formula is long. Is there a better solution?
You can multiply by 1.0:
int a{5}, b{2}, c{9};
double d = 1.0 * a / b + 1.0 * c;
And when you work with sums you can add to 0.0:
double d = 0.0 + a - b + c;
Most compilers perform optimization such that the meaningless operation is not evaluated. Only type conversion is done.
Remember that you only need to cast the first member in each division/multiply group. Do so in any manner that seems reasonable. And simple addition/substraction (with no other type multipliers/divisors) is casted too. Compilers guarantee casting. So your example:
double d = (double)a / (double)b + (double)c;
Really may be rewritten like this:
double d = (double)a / b + c;
double d = 1.0 * a / b + c;
double d = static_cast<double>(a) / b + c;
Some more examples:
double d = (double)a / b + (double)c / d + e;
double d = 1.0 * a / b + 1.0 * c / d + e;
double d = static_cast<double>(a) / b + static_cast<double>(c) / d + e;
This works but all you need is a single 1.0* in front of a
int a{5},b{2},c{9};
double d = (double)a / (double)b + (double)c;
int a{5},b{2},c{9};
double d = 1.0*a / b + c;
The rules of precedence and implicit conversion will cause all the variables to be converted to doubles.
One thing to be careful of is grouped variables which will need to have their own 1.0* or 0.0+ as appropriate:
int a{5},b{2},c{9};
double d = a / (0.0 + b + c);
int a{5},b{2},c{9};
double d = a / (1.0 * b * c);
Alternately, one use use a static cast on the associated variable. I prefer the smaller version as the 1.0* or 0.0+ both scream out implicit conversion to doubles.
int a{5},b{2},c{9};
double d = a / (static_cast<double>(b) * c);
Is there a better solution?
Yes. Express intent through functions.
Marvel as the optimiser emits perfectly efficient assembler. Enjoy the accolades of your colleagues who gaze in wonder at your awesomely readable and maintainable code:
#include <iostream>
auto a_over_b_plus_c(double a, double b, double c)
{
double d = a / b + c;
return d;
}
int main()
{
int a = 5, b = 2, c = 9;
std::cout << a_over_b_plus_c(a, b, c) << std::endl;
}
For fun, here's a solution based on tuples & lambdas:
#include <iostream>
#include <tuple>
template<class T, class...Args>
auto to(Args&&...args)
{
return std::make_tuple(T(std::forward<Args>(args))...);
}
int main()
{
int a = 5, b = 2, c = 9;
auto calc = [](auto&& vals) {
auto& a = std::get<0>(vals);
auto& b = std::get<1>(vals);
auto& c = std::get<2>(vals);
return a / b + c;
};
auto result = calc(to<double>(a, b, c));
std::cout << result << std::endl;
}
... and something perhaps more readable...
#include <iostream>
#include <tuple>
#include <complex>
template<class T, class F, class...Args>
auto with(F f, Args&&...args)
{
return f(T(std::forward<Args>(args))...);
}
int main()
{
int a = 5, b = 2, c = 9;
auto calc = [](auto&& a, auto&& b, auto&& c) {
return a / b + c;
};
auto result = with<double>(calc, a, b, c);
auto result2 = with<float>(calc, a, b, c);
auto result3 = with<std::complex<double>>(calc, a, b, c);
auto result4 = with<std::complex<float>>(calc, a, b, c);
std::cout << result << std::endl;
std::cout << result2 << std::endl;
std::cout << result3 << std::endl;
}
Related
How to correctly calculate the coefficients of the Bezout ratio for the case of negative numbers in the implementation of the extended euclidean algorithm? Here is my code:
#include <iostream>
#include <cmath>
#include <tuple>
using namespace std;
tuple<int, int, int> xgcd(int a, int b, int s1 = 1, int s2 = 0, int t1 = 0, int t2 = 1) {
if (b == 0) {
return {abs(a), s1, t1};
}
int q = a / b;
return xgcd(b, a - q * b, s2, s1 - q * s2, t2, t1 - q * t2);
}
int main(double argc, char ** argv) {
tuple<int, int, int> result = xgcd(-10, -15);
cout << get<0>(result) << " " << get<1>(result) << " " << get<2>(result) << endl;
return 0;
};
In the presented case (-10, -15), the GCD is calculated correctly, but the Bezout coefficients require inverting the sign. What is the right way to deal with them? Thank you in advance!)
I figured out the problem. The solution is: replace a and b with their modules at the very beginning of the algorithm. But then the Bezout's coefficients will be found incorrectly. Let, for example, a < 0, and b > 0. Then after changing the sign of a, the resulting Bezout's identity will look like this:
gcd(a, b) = s(-a) + tb (in terms of -a and b)
or
gcd(a, b) = -sa + tb (in terms of a and b).
In general , for a and b arbitrary signs , this will be written
gcd(a, b) = sgn(a)sa + sgn(b)tb.
Thus, if we change the sign of a, then we must change the sign of s. Similarly, if we change the sign of b, then we must change the sign of t. Thus, the algorithm in recursive form will be written as follows:
tuple<int, int, int> xgcd(int a, int b, int sign_a = 0, int sign_b = 0, int s1 = 1, int s2 = 0, int t1 = 0, int t2 = 1) {
if (!sign_a) {
sign_a = a < 0 ? -1 : 1;
}
if (!sign_b) {
sign_b = b < 0 ? -1 : 1;
}
a = abs(a);
b = abs(b);
if (b == 0) {
return {a, sign_a * s1, sign_b * t1};
}
int q = a / b;
return xgcd(b, a - q * b, sign_a, sign_b, s2, s1 - q * s2, t2, t1 - q * t2);
}
using namespace std;
#include <iostream>
#define _USE_MATH_DEF
#include <conio.h>
#include <cmath>
int main()
{
const double e = 2.71;
double x, a, b, c, A, B, C, M;
cout << "Enter the value of x, a, b and c: ";
cin >> x >> a >> b >> c;
A = x + pow(sqrt(x + a), 3);
// cout << A;
B = x - sqrt((abs(x - b)));
// cout << B;
C = A / B;
M = pow(e, -1 * c) * C;
cout << "The result of function is " << M;
_getch();
return 0;
}
For example, lets define x=1, a=4, b=5, c=1.
Calculator returns M as -0.9547605358, but code calculates M as -4.49459.
This is mathematical formula that I need to code:
Here I see some problems, namely A must be
A = x + pow(sqrt(x + a), 1.0/3.0);
B and C definition is correct, but M must be
M = pow(e, -1 * c * x) * C;
I would also like to point out that conio.h is a non standard header file and _getch() is non standard.
So I've decided to take a stab at implementing Karatsuba's algorithm in C++ (haven't used this language since my second coding class a life time ago so I'm very very rusty). Well anyhow, I believe that I've followed the pseudocode line by line but my algorithm still keeps popping up with the wrong answer.
x = 1234, y = 5678
Actual Answer: x*y ==> 7006652
Program output: x*y ==> 12272852
*Note: I'm running on a mac and using the following to create the executable to run c++ -std=c++11 -stdlib=libc++ karatsuba.cpp
Anywho, here's the code drafted up and feel free to make some callouts on what I'm doing wrong or how to improve upon c++.
Thanks!
Code:
#include <iostream>
#include <tuple>
#include <cmath>
#include <math.h>
using namespace std;
/** Method signatures **/
tuple<int, int> splitHalves(int x);
int karatsuba(int x, int y, int n);
int main()
{
int x = 5678;
int y = 1234;
int xy = karatsuba(x, y, 4);
cout << xy << endl;
return 0;
}
int karatsuba(int x, int y, int n)
{
if (n == 1)
{
return x * y;
}
else
{
int a, b, c, d;
tie(a, b) = splitHalves(x);
tie(c, d) = splitHalves(y);
int p = a + b;
int q = b + c;
int ac = karatsuba(a, c, round(n / 2));
int bd = karatsuba(b, d, round(n / 2));
int pq = karatsuba(p, q, round(n / 2));
int acbd = pq - bd - ac;
return pow(10, n) * ac + pow(10, round(n / 2)) * acbd + bd;
}
}
/**
* Method taken from https://stackoverflow.com/questions/32016815/split-integer-into-two-separate-integers#answer-32017073
*/
tuple<int, int> splitHalves(int x)
{
const unsigned int Base = 10;
unsigned int divisor = Base;
while (x / divisor > divisor)
divisor *= Base;
return make_tuple(round(x / divisor), x % divisor);
}
There are a lot of problems in your code...
First, you have a wrong coefficient here:
int q = b + c;
Has to be:
int q = c + d;
Next, the implementation of splitHalves doesn't do the work. Try that:
tuple<int, int> splitHalves(int x, int power)
{
int divisor = pow(10, power);
return make_tuple(x / divisor, x % divisor);
}
That would give you the "correct" answer for your input, but... that is not a Karatsuba method.
First, keep in mind that you don't need to "split in halves". Consider 12 * 3456. splitting the first number to halves mean a = 0, b = 12, while your implementation gives a = 1, b = 2.
Overall Karastuba works with arrays, not integers.
Can someone correct this code please.
#include <iostream>
using namespace std;
int main()
{
int a;
int b;
int c;
double d;
double e;
double f;
double g;
f = a / b;
g = b / a;
c = 0;
cin >> a;
cin >> b;
f = a / b;
g = b / a;
if (a == b)
{
cout << a << endl;
return 0;
}
else if (f == int(f))
{
cout << a << endl;
return 0;
}
start:
while (a * b > c)
c = c + 1;
d = c / a;
e = c / b;
if (d == int(d))
if (e == int(e))
{
cout << c << endl;
return 0;
}
else if (d != int(d))
goto start;
else if (e != int(e))
goto start;
if (a * b <= c)
cout << a * b << endl;
}
No matter what the
else if(f==int(f))
code is always executed. Eg. I put in 3 and 5 and even though 3/5 gives a decimal the else if is always executed and outputs 3. WHAT AM I MISSING HERE?
The primary error in your code leading to the problem with the if statement is the integer division. You have to cast the operands to doubles to perform floating point division:
cin >> a;
cin >> b;
f = double(a) / double(b);
g = double(b) / double(a);
There are other issues to clean up, but this is the one that leads to your question.
These expression, though they are assigning to double variables, calculate integer divisions.
f = a / b;
g = b / a;
d = c / a;
e = c / b;
I.e. what gets assigned to the doubles are integer values.
Your if-conditions basically check for integer values and hence always evaluate to true.
In order to avoid the integer division and get actual floating point values assigned to the doubles, you need to make sure early that the compiler interprets them accordingly. E.g.:
f = (1.0*a) / b;
g = (1.0*b) / a;
d = (1.0*c) / a;
e = (1.0*c) / b;
And, as a comment points out, better always init all your variables (even if here a,b,c would be enough).
int a=1;
int b=1;
int c01;
double d=1.0;
double e=1.0;
double f=1.0;
double g=1.0;
You just need to define type a and b as double not int.
I need to find the maximum of the function between the specific ratio. The code below show "Method of the golden ratio", which could find the maximum of the funciton. The problem is when I use a exp() function in [0.,10.] the result is about 10, but it should be about 20k. Do you know where is the problem? Have you got some other methods to find the maximum of the function?
#include <iostream>
#include <cmath>
using namespace std;
double goldenRatioMethodMax(double(*p_pFunction)(double), double a, double b)
{
double k = (sqrt(5.) - 1.) / 2.;
double xL = b - k * (b - a);
double xR = a + k * (b - a);
while (b - a > EPSILON)
{
if (p_pFunction(xL) > p_pFunction(xR))
{
b = xR;
xR = xL;
xL = b - k*(b - a);
}
else
{
a = xL;
xL = xR;
xR = a + k * (b - a);
}
}
return (a + b) / 2.;
}
int main(int argc, char **argv)
{
cout << goldenRatioMethodMax(exp, 0.,10.);//the answer is about 10 but it should be about 20k
return 0;
}
The problem is that you return the value at which the max is found, not the max itself. Just change the last line of the function to return p_pFunction((a + b) / 2.); and it will generate the expected output.