【问题标题】:Including arithmetic operations when defining a constant定义常量时包括算术运算
【发布时间】:2013-02-15 06:55:23
【问题描述】:

所以我经常看到这样的:

#define gf_PI  f32(3.14159265358979323846264338327950288419716939937510)
#define gf_PIhalf  f32(3.14159265358979323846264338327950288419716939937510 * 0.5)

这意味着每次我在代码中使用 gf_PIhalf 时都会计算一半的 PI 值,对吗?
直接写下半个 PI 的值不是更好吗?

这样做不是更好吗:

#define gf_PI f32(3.14159265358979323846264338327950288419716939937510)
const float gf_PIHalf = gf_PI * 0.5f;    // PIHalf is calculated once

最后,这样做不是最好的吗(以及为什么这似乎不是一种常见的做法):

const float gf_PI = 3.14159265358979323846264338327950288419716939937510;
const float gf_PIHalf = gf_PI * 0.5f;

【问题讨论】:

  • 你真的关心你的程序是否多做一个乘法吗?真的那么重要吗?
  • 这是一个很好的问题。我曾经问过一个类似的关于内存限制和效率的问题,我认为我收到的标准答案类似于“老实说,按照这个速度,没关系。就是这么少的数据量,效率比没有”不会受到太大的打击。”我想在这种情况下,你会发现程序的效率并不一定会受到 VS 的影响。您每次都可以信任的重新计算的想法。如果你对算术有信心,我会追求纯粹的效率。
  • 看,一个好的编译器将even a complete mess like this优化成一个常量...
  • @Smash:嗯,它不太可能成为瓶颈,但如果乘法运算实际上每次都会发生并且它会在一个经常调用的关键循环中使用,那么我看不到为什么不使用其他解决方案之一来确保它不会发生。
  • @plast1K:这是一个常数。每次都重新计算它不会让我不再信任它。

标签: c++ constants c-preprocessor


【解决方案1】:

这意味着每次我在代码中使用 gf_PIhalf 时都会计算一半的 PI 值,对吧?

不,不太可能。

您可以合理地依靠您的编译器在编译时而不是运行时进行乘法运算。

【讨论】:

    【解决方案2】:

    您的结论有些正确,除了#define 版本几乎肯定会在编译时解决,并且类型 const 全局变量是不常见的做法。它们是现代优秀代码中的常见做法。 #defines 几乎不适合这种用途。 最佳 做法是在未命名的命名空间中定义文件范围全局变量:

    namespace
    {
        const float g_SomeGlobal = 123.456f;
    }
    

    这可以防止翻译单元之外的任何人“看到”g_SomeGlobal

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-31
      相关资源
      最近更新 更多