1. ホーム
  2. c

[解決済み】二乗した数字を合計するとき、負数やゼロを明示的に処理する必要がありますか?

2022-04-07 08:36:08

質問

最近、私のクラスでテストがありました。その中で、次のような問題がありました。

ある数字が与えられたとき n の桁数の合計を返す関数を C/C++ で書いてください。 二乗 . (が重要です)。その 範囲 n は [ -(10^7), 10^7 ]です。例 もし n = 123 とすると、この関数は 14 (1^2 + 2^2 + 3^2 = 14) を返すはずです。

これが、私が書いた関数です。

int sum_of_digits_squared(int n) 
{
    int s = 0, c;

    while (n) {
        c = n % 10;
        s += (c * c);
        n /= 10;
    }

    return s;
}

私には正しく見えた。それで、今テストが返ってきて、先生は私が理解できない理由で私にすべてのポイントを与えなかったことがわかりました。先生によると、私の関数が完全であるためには、次の詳細を追加する必要があったそうです。

int sum_of_digits_squared(int n) 
 {
    int s = 0, c;

    if (n == 0) {      //
        return 0;      //
    }                  //
                       // THIS APPARENTLY SHOULD'VE 
    if (n < 0) {       // BEEN IN THE FUNCTION FOR IT
        n = n * (-1);  // TO BE CORRECT
    }                  //

    while (n) {
        c = n % 10;
        s += (c * c);
        n /= 10;
    }

    return s;
}

という論調ですが、この数値は n は [-(10^7), 10^7] の範囲にあるので、負の数になる可能性があります。しかし、私自身のバージョンの関数がどこで失敗するのかがわかりません。私の理解が正しければ while(n)while(n != 0) , ない while (n > 0) というように、私のバージョンの関数では、数値は n を使えば、ループに入るのに失敗することはないでしょう。同じように動作するのです。

そして、自宅のパソコンで両方のバージョンの関数を試してみましたが、試したすべての例でまったく同じ答えが返ってきました。そこで sum_of_digits_squared(-123) と同じです。 sum_of_digits_squared(123) (と等しい)。 14 ) (明らかに加えるべきであったディテールを除いても)。確かに、数字の桁を(重要度の低いものから高いものへと)画面に表示しようとすると 123 の場合は、次のようになります。 3 2 1 で、その中に -123 の場合は -3 -2 -1 (これは実はちょっと面白いのですが)。しかし、この問題では、桁を二乗しているので、問題にはならないでしょう。

では、誰が間違っているのでしょうか?

EDIT : 失礼しました、指定するのを忘れていて、重要だと知りませんでした。私たちのクラスとテストで使用するCのバージョンは、C99または 新しい . だから、(コメントを読んで)私のバージョンはどのような方法でも正しい答えを得ることができるだろうと推測しています。

どのように解決するのですか?

コメント欄で浸透している議論をまとめる。

  • を事前にテストする正当な理由はありません。 n == 0 . その while(n) テストはこのケースを完全に処理します。
  • 先生は、まだ以前の時代に慣れているようで、その頃の結果は % という負のオペランドの定義が異なっていました。 いくつかの古いシステム(特に、Dennis Ritchie が最初に C を開発した PDP-11 上の初期の Unix など)では a % b 常に 範囲内 [0 .. b-1] ということは,-123 % 10 が 7 であることを意味する。 n < 0 が必要だろう。

しかし、2番目の弾丸は、それ以前の時代にのみ適用されます。 CとC++の両方の標準の現在のバージョンでは、整数の除算は0に向かって切り捨てられると定義されているので、次のことがわかります。 n % 10 の下1桁が(場合によっては負の)数値になることが保証されています。 n の場合でも n が負になる。

ということは、質問の答えは の意味は何ですか? while(n) ?" と全く同じです。 while(n != 0) "です。 に対する答えは このコードは、正の値だけでなく負の値に対しても正しく動作するのでしょうか? n ?quotです。 "はい、標準に準拠した最新のコンパイラではそうです。 という質問に対する答えは "では、なぜ講師はそれをマークダウンしたのでしょうか?"。 は、1999年にCに、2010年くらいにC++に起こった重要な言語再定義を知らないのだろう。