doubleで係数を使用できませんか?


185

C ++のプログラム(g ++を使用してコンパイル)があります。2つのdoubleをオペランドとしてモジュラス関数に適用しようとしていますが、次のエラーが発生します。

エラー:タイプ 'double'および 'double'からバイナリ 'operator%'への無効なオペランド

これがコードです:

int main() {
    double x = 6.3;
    double y = 2;
    double z = x % y;
}

12
前述のように、fmod()は必要な関数を提供します。まだ言及されていないように、第2オペランドの丸め誤差fmodが予期しない動作を引き起こす可能性があることを認識することが重要です。たとえば、fmod(1, 0.1);数学的にはゼロでなければなりませんが、実際にはほぼ0.1になります。誤差の程度は、商の大きさによって増加します。たとえば、fmod(9E14, 0.1);評価結果は約0.05です。これは、数学的な観点から言えば、間違いです。
スーパーキャット2013年

1
@supercat詳細は素晴らしいでしょう。私はあなたが言うことを真実にさせるために舞台裏で何が起こっているかについての考えを持っていると思いますが、あなたが言うことが真実である理由を見るのは良いでしょう。それが舞台裏でどのように機能するかを見るのは興味深いでしょう(私は理解していると思いますが、非常に簡単に間違っている可能性があります)。
ラスタジェダイ2016年

3
浮動小数点値は、正確な整数の倍数または2の累乗の分数を表します。たとえば、整数リテラル0.1は正確に3602879701896397/36028797018963968です(後者の値は2の累乗です)。 fmod(x,0.1)数値「1/10」で除算するのではなく、xをその正確な分数で除算し、残りを取得します。
スーパーキャット2016年

回答:


272

%オペレータは整数です。あなたはfmod()関数を探しています

#include <cmath>

int main()
{
    double x = 6.3;
    double y = 2.0;
    double z = std::fmod(x,y);

}

Qt用にC ++でプログラミングしていますが、fmodにバグがあります。fmod(angle、360)の結果は360(WAT ?!)になる可能性があります
Paul

7
@Paul:それはおそらくバグではありません。たとえばの場合angle、との359.9999999両方がanglefmod(angle, 360)表示される可能性があります360。(必要に応じてさらに9を追加します。)たとえば、50桁の精度で値を印刷してみます。
キーストンプソン、

@Paul QtのQString :: formatは丸められます。それが非常に重要な場合は、自分で丸めるか、「360」の出力を確認して、独自の値に置き換える必要があります。
jfh


5

fmod()から使用してください<cmath>。Cヘッダーファイルを含めない場合:

template<typename T, typename U>
constexpr double dmod (T x, U mod)
{
    return !mod ? x : x - mod * static_cast<long long>(x / mod);
}

//Usage:
double z = dmod<double, unsigned int>(14.3, 4);
double z = dmod<long, float>(14, 4.6);
//This also works:
double z = dmod(14.7, 0.3);
double z = dmod(14.7, 0);
double z = dmod(0, 0.3f);
double z = dmod(myFirstVariable, someOtherVariable);

3
Cヘッダーファイルを含めないのはなぜですか?それが目的です。
キーストンプソン、

2

あなたはできる独自のモジュラス機能を実装するあなたのためにそれを行うには:

double dmod(double x, double y) {
    return x - (int)(x/y) * y;
}

次に、を使用dmod(6.3, 2)して残りを取得できます0.3


まだ完璧な解決策ではありません。x = 10.499999999999998、y = 0.69999999999999996は0.0ではなく0.69999999999999929を返します
タルピスタ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.