0

私は(あまり成功せずに)短いc ++関数を書き込もうとしています:

2桁(double x、int b、int d)

これは、数値xの基数b展開のd番目の桁を返します。これは、正または負の場合があり、分数の場合もあります。dが負の場合、10進数の後の数字を返す必要があります(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 ) );
}

1桁に小数部を含めるのは意味がないため、戻り値のタイプをからに変更しdoubleました。また、0は数字intではないため、0には戻りません。.0番目の場所の値は1番目の場所です。

また、これはマイナス記号を無視します。負の数の「base-b展開」を定義していません。関数を調整して、bの補数表記などを返すことができます。

代入xすることで、これを1行にすることができるのでconstexpr、数学関数もあるプラットフォームでの要件を満たしconstexprます。

于 2013-01-02T07:22:00.673 に答える
0

これを2つのステップで実行しましょう。

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;
 }

新しいベースには、10、11などの余りを表す「A」や「B」などの数字を含めることができるため、文字列として返す必要があります。次に、次のように、返された文字列を試してみることができます。

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

負のサポートの場合、負のdの定義方法に基づいて、文字列インデックスを適切に使用できます。

于 2013-01-02T07:21:22.593 に答える