【问题标题】:Implementing Operator Overloading with Logarithms in C++在 C++ 中使用对数实现运算符重载
【发布时间】:2010-05-05 03:02:34
【问题描述】:

我在使用 C++ 中的运算符重载实现对数类时遇到了一些问题。

我的第一个目标是如何实现changeBase 方法,我一直在努力解决它。

我试图了解更改对数底数背后的数学原理,但我没能做到。谁能给我解释一下?

我的第二个目标是能够执行左操作数是 double 而右操作数是对数对象的操作。

这是我的日志类的 sn-p:

// coefficient: double
// base: unsigned int
// result: double
class _log {

 double coefficient, result;
 unsigned int base;

public:

 _log() {
  base = 10;
  coefficient = 0.0;
  result = 0.0;
 }
 _log operator+ ( const double b ) const;
 _log operator* ( const double b ) const;
 _log operator- ( const double b ) const;
 _log operator/ ( const double b ) const;
 _log operator<< ( const _log &b );

 double getValue() const;

 bool changeBase( unsigned int base );
};

你们太棒了,感谢您的宝贵时间。

【问题讨论】:

  • 您能否更具体地谈谈您在实施基地变更时遇到的困难?
  • @James,对不起。我将编辑我的答案。
  • coefficientnumber 是什么?见en.wikipedia.org/wiki/Common_logarithm:是通用名称characteristicmantissa吗?
  • 结果是什么?我只看到它变得随机化。结果应该从函数返回,而不是永久存储在这样的结构中。
  • 另外,对数的小数部分在哪里?如果你想在除 3 之外的基数中表示数字 3,你会怎么做?

标签: c++ operator-overloading logarithm


【解决方案1】:

我的第二个目标是能够执行左操作数为双精度且右操作数为对数对象的操作。

为此,您需要将运算符声明为命名空间范围内的非成员函数(即不在_log 的定义中),例如,

_log operator+(const double a, const _log& b);

如果你需要访问_log的私有成员,你可以在_log的定义中声明它为朋友:

friend _log operator+(const double a, const _log& b);

请注意,以下划线开头的名称(例如,_log)保留给全局命名空间中的实现;如果下划线后跟大写字母或另一个下划线,则在任何地方都保留。选择不同的类名是个好主意。

【讨论】:

  • 在非成员运算符的情况下,尽量避免说朋友是很好的。由于您已经有一个成员加法运算符,因此将另一个方向实现为非朋友非成员函数是微不足道的。
【解决方案2】:

一些事情

  1. 在班级前面使用 _ 是一个非常糟糕的主意 (tm)。来自 c++ 标准:

17.4.3.2.1 全局名称 [lib.global.names] 某些名称和函数签名集总是保留给 实现:

  • 每个名称都包含双下划线 (_ _) 或以 下划线后跟大写字母 字母 (2.11) 保留给 实现任何用途。
  • 以下划线开头的每个名称都保留给 用作名称的实现 全局命名空间。165

165) 此类名称也保留在命名空间 ::std (17.4.3.1) 中。

  1. 我猜你使用 _log 而不是 log 因为与 cmath 中的 log() 冲突。出于这个原因,将您自己的类保留在标准命名空间中是一个非常糟糕的主意。也许该标准的下一个版本将提供 _log 或 Logarithm 类? 在namespace somename {} 中封装你自己的类并使用somename::Logarithm() 引用它

  2. 正如其他人已经提到的那样,您需要将您的运算符重载声明为朋友。而不是你所拥有的

    log operator+ ( const double b ) const;

    改成

    friend log operator+(const double d, const log& l);
    

    并在命名空间范围内定义函数。

  3. 这是基本公式变化的数学运算

  4. 数学中的系数是指乘以对数的部分。所以如果你有 一个 log_b(x) = y

    A 是系数,B 是基数,Y 是结果(或其他名称)

【讨论】:

    【解决方案3】:

    一些想法:

    1. 请勿使用前导下划线命名。此类标识符在 C 和 C++ 中具有放射性。
    2. 在浮点运算之前定义对数之间的运算。
    3. 将 #2 与 James 的建议结合起来:

      friend logarithm operator+( const logarithm &l, const logarithm &r );
      
    4. 定义一个转换构造函数以从浮点数生成logarithm

      logarithm::logarithm( double f );
      

      现在 C++ 会将double 转换为logarithm 中的1.0 + my_logmy_log + 1.0

    5. 在您的班级中实施natural logarithms。不要打扰base
    6. 根据函数定义基本转换:

      double alternate_base( double base ) const;
      

      碱基转换只是将logarithm 除以备用碱基的自然对数。在单个 double 中一起返回整数和小数部分可能是最方便的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-21
      • 1970-01-01
      • 2013-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多