Euri Pinhollow - 1 month ago 5
C Question

# Deterministic way of saying "promote everything to floating before calculation" in C++

Given that I'd prefer to keep numbers in my program as

`int`
s or whatever integral, what is the most convenient way of doing an arbitrary arithmetic with floating point equivalents of those numbers?

Say, I have

``````int a,b,c,d;
double x;
``````

And I want to write

``````x=a/b/c/d+c/d+a;
``````

without turning the expression into mess by putting conversions everywhere in parsed operator tree leafs like

``````x=(double)a/b/c/d+(double)c/d+a;
``````

Is it doable with C-style macro (recursive or not)? Should it be done with new class and overloaded operators?

``````x=a/b/c/d+c/d+a;
``````

This is a pretty complex expression. Better give it a name:

``````double complex_expression(double a, double b, double c, double d) {
return a/b/c/d+c/d+a;
}
``````

Now when you call that with integer arguments, since the parameters are of type `double` the arguments get converted to `double` using the usual arithmetic conversions:

``````int a,b,c,d;
// Init them somehow
double x = complex_expression(a,b,c,d);
``````

With a C++11 lambda ...

``````int a,b,c,d;
// Init them somehow
double x = [](double a, double b, double c, double d) {
return a/b/c/d+c/d+a; }(a,b,c,d);
``````

... works, but IMO somehow looks clumsy.

Slightly better?

``````double x = [a = (double)a, b = (double)b, c = (double)c, d = (double) d] {
return a/b/c/d+c/d+a; }();
``````

Oh, and if you're in for some macro fun:

``````#define SPLICE_2(l,r) l##r
#define SPLICE_1(l,r) SPLICE_2(l,r)
#define SPLICE(l,r) SPLICE_1(l,r)

#define TREAT_AS(type, name) name = static_cast<type>(name)

#define TREAT_ALL_AS_HELPER_0(type)
#define TREAT_ALL_AS_HELPER_1(type, name)  TREAT_AS(type, name)
#define TREAT_ALL_AS_HELPER_2(type, name, ...) TREAT_AS(type, name), TREAT_ALL_AS_HELPER_1(type, __VA_ARGS__)
#define TREAT_ALL_AS_HELPER_3(type, name, ...) TREAT_AS(type, name), TREAT_ALL_AS_HELPER_2(type, __VA_ARGS__)
#define TREAT_ALL_AS_HELPER_4(type, name, ...) TREAT_AS(type, name), TREAT_ALL_AS_HELPER_3(type, __VA_ARGS__)
#define TREAT_ALL_AS_HELPER_5(type, name, ...) TREAT_AS(type, name), TREAT_ALL_AS_HELPER_4(type, __VA_ARGS__)
// expand as you will

#define TREAT_ALL_AS(type, count, ...) SPLICE(TREAT_ALL_AS_HELPER_, count)(type, __VA_ARGS__)
``````

Now use as

``````double x = [TREAT_ALL_AS(double, 4, a, b, c, d)] {
return a/b/c/d+c/d+a; }();
``````

But to be honest, IMO its best to just write a named function.