在C++中说"在计算前促进一切浮动"的确定性方法

Eur*_*low 10 c c++ floating-point integer-promotion

鉴于我更喜欢​​将程序中int的数字保存为s或任何积分,使用这些数字的浮点等值进行任意算术的最方便的方法是什么?

说,我有

int a,b,c,d;
double x;
Run Code Online (Sandbox Code Playgroud)

我想写

x=a/b/c/d+c/d+a;
Run Code Online (Sandbox Code Playgroud)

通过在解析的运算符树叶子中放置转换,而不是将表达式变为混乱

x=(double)a/b/c/d+(double)c/d+a;
Run Code Online (Sandbox Code Playgroud)

是否可以使用C风格的宏(递归与否)?应该用新类和重载运算符来完成吗?

Dan*_*our 11

x=a/b/c/d+c/d+a;
Run Code Online (Sandbox Code Playgroud)

这是一个非常复杂的表达.最好给它起个名字:

double complex_expression(double a, double b, double c, double d) {
  return a/b/c/d+c/d+a;
}
Run Code Online (Sandbox Code Playgroud)

现在,当您使用整数参数调用它时,由于参数是类型,double因此参数将double使用通常的算术转换转换为:

int a,b,c,d;
// Init them somehow
double x = complex_expression(a,b,c,d);
Run Code Online (Sandbox Code Playgroud)

使用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);
Run Code Online (Sandbox Code Playgroud)

......工作,但IMO看起来很笨拙.

稍微好一些?

double x = [a = (double)a, b = (double)b, c = (double)c, d = (double) d] {
    return a/b/c/d+c/d+a; }();
Run Code Online (Sandbox Code Playgroud)

哦,如果你想要一些宏观的乐趣:

#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__)
Run Code Online (Sandbox Code Playgroud)

现在使用as

double x = [TREAT_ALL_AS(double, 4, a, b, c, d)] {
  return a/b/c/d+c/d+a; }();
Run Code Online (Sandbox Code Playgroud)

您还可以自动计算可变参数宏参数的数量.


但说实话,IMO最好只写一个命名函数.

  • @KishanKumar然后,为了降低整体复杂性,将单个表达式*命名为*会更好.功能并不昂贵,你可以拥有很多功能(虽然你可能希望它们是静态的,假设它们只使用一次) (2认同)