7

1/60または1/(60 * 60)を除算しようとすると、0になります。デバッガウィンドウでも。2/3または2.5/6で結果が得られるため、私はそれが何であるか少し混乱しています。

私のコード:

int main()
{   
    double k1 = 1/60;
    cout << k1
        << endl;
    double k2 = 1/(60*60);
    cout << k2
        << endl;

    return 0;
}

私はあなたの助けに感謝します。

4

3 に答える 3

11

両方のオペランドが整数であるため、コンパイラーは整数除算を実行します(小数部は計算されません)。(他の例のように)オペランドの少なくとも1つが浮動小数点型である場合、もう1つがプロモートされ、浮動小数点除算が実行されます。

修正

浮動小数点型(doubleまたはfloat)のオペランドの少なくとも1つを作成します。あなたはこれを行うことができます例えば:

  • それをdoubleリテラル2にします(60整数、60.0またはで60.さえdouble60.fですfloat
  • キャスト(double(60)(double)60)を使用します。

個人的には、直接doubleリテラルを使用することを好みます。キャストが中途半端なコンパイラでパフォーマンスを低下させるわけではありませんが、正しいタイプのリテラルを使用するだけでは「間違った」冗長な感じがします。(明らかに、両方のオペランドが変数であり、リテラルではない場合、キャストを使用する必要があります)

一般的な反対意見

  • 「しかし、私はそれをdouble!に割り当てています」

    多くの初心者は、結果をaに割り当てるdoubleことは、コンパイラーへのある種のヒントになるはずだと考えているため、この事実に混乱しています。実際、そうではありません。

    式に対して行われる計算/プロモーションは、宛先のタイプから完全に独立しています。これは、最後のステップにすぎません。部分式は、結果がどのように使用されるかに関係なく、それらが何であるかについて評価されるため、すべての型の昇格/操作は、オペランドの型にのみ依存します。

  • なぜ整数除算が必要なのですか?

    いくつかの言語は、引数が両方とも整数(VB6、IIRCなど)の場合でも、初心者にとってより直感的であるため、浮動小数点除算を自動的に実行します。これはC/C ++の場合とは異なります。引数が整数の場合、除算は整数です。多くの場合、小数は気にしないため、および/またはパフォーマンス上の理由から、FPU(背景哲学)を使用しない方が望ましいためです。 CおよびC++では、「使用しないものに対して料金を支払う必要はありません」)。

    明らかに、この問題は、積分除算用の別の演算子を使用して対処できた可能性があります(VBも、\)を使用しますが、IMHOには、C++に十分な演算子があります。:)


  1. Nitpickersのコーナー:はい、ここでは実際には初期化であり、割り当てではありませんが、同じ種類の誤解について話しています。
  2. 「リテラル」は、ソースコードに含まれる値です。
于 2012-10-31T18:00:26.793 に答える
2

分母も10進数である必要があります。

double k1 = 1/60.0; //Should work

そうしないと、プログラムは基本的にすべての小数を切り捨てます。

LITTLE EXTRA:分母が変数の場合、次のようにキャストする必要があります。

double k2 = 1/(double)myDenom;
于 2012-10-31T17:59:07.997 に答える
2

この行double k1 = 1/60は、コンパイラによってコンパイル時定数として評価されます。数値の末尾に「.0」がないため、1/60整数除算によって評価され、したがって0になります。

于 2012-10-31T18:00:00.027 に答える