0

我正在尝试(没有多大成功)编写一个简短的 c++ 函数:

两位数(双 x,int b,int d)

返回数字 x 的 base-b 扩展中的第 d 位,可以是正数或负数,并且可以是分数。当 d 为负数时,它应该返回小数点后的数字(对于 d=0,它的下定义,所以说在这种情况下它返回 0)。例如:

    const double x = 25.73;
    for (int n = -5; n <= 5; n++)
            cout<<digit(x,10,n)<<' ';

应该打印:0 0 0 3 7 0 5 2 0 0 0

该函数必须仅使用循环、if、exp、pow、log、floor 和 ceil。即,没有 sprintf 技巧等。

谢谢!!!

编辑:为简单起见,假设 2<=b<=10

编辑:也请避免使用 mod,只使用基于 pow-exp-log-floor-ceil 的解决方案

4

2 回答 2

2

这似乎是最直接的实现,而且似乎工作得很好。

int digit( double x, int base, int index ) {
    // shift number (mult by power of base) so desired digit is in one's place
    x = std::abs( x ) * std::pow( base, - index );
    // fmod strips higher digits; floor strips lower digits, leaving result.
    return std::floor( std::fmod( x, base ) );
}

我将返回类型从更改为doubleint因为在数字中包含小数是没有意义的。它不会返回.0,因为这又不是数字。第 0 个位置的值是一个位置。

这也忽略了减号;您没有为负数定义“base-b 扩展”。您可以调整函数以返回 b 的补码符号或其他任何东西。

通过替换x你可以把它变成一行,这样它就可以满足constexpr数学函数所在平台的要求constexpr

于 2013-01-02T07:22:00.673 回答
0

让我们分两步来做。

1.将数字转换为基数b

2.找到第d位并返回。

拆分任务的原因是因为如果你重复调用同一组基数和数字并且只为不同的d,那么我们可以将数字缓存在新的基数中。例如下面的函数从基数10转换一个数字a , 以b为底。我很好奇如何处理分数。

string changeBase(int a,int b)
{
  string A="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  string res="";
  while(a>=b)
  {
      res=A[a%b]+res;
      a=a/b;
  }
  return res;
 }

我们需要以字符串的形式返回,因为新的基数可以包含“A”或“B”等数字,它们表示 10、11 等的余数。然后我们可以使用返回的字符串,如下所示:

 string A=changeBase(24,2);
 cout<<A[0];//for some d

对于负支持,您可以根据您为负d定义它的方式适当地使用字符串索引。

于 2013-01-02T07:21:22.593 回答