はこねのはこ

はこねさんの備忘録

C++の少数の出力結果が丸められてしまったのでsetprecisionマニピュレータをつかった。

はじめに

先日AtCoderさんのABC168に参加した時、
問題Cの出力結果の精度がどうしても欲しいところまで出なくて悩んでいた。 atcoder.jp

4.56425719433005553554
...と割り切れない値のはずが、
4.56426
と表示されていた。

結論

setprecisionマニピュレータを使って解決した。

cout << fixed << setprecision(20) << getHoge() << endl;

コンテスト中に悩んでいたコード

仕様がわからずとりあえず精度を上げればなんとかならないかと考えて無意味にキャストしている。

#define ld long double

ld getSqrtl(ld x1,ld y1,ld x2,ld y2){
    ld x = x1 - x2;
    ld y = y1 - y2;
    ld ans = (ld)sqrtl( x*x + y*y );
    return ans;
}

int main() {
    ld A,B,H,M;
    //              時間  分
    cin >> A >> B >> H >> M;

    ld do2 = (ld)360.0 * ((ld)M/(ld)60.0);
    ld ra2 = do2 * ((ld)M_PI/(ld)180.0);
    ld x2 = B * cosl(ra2);
    ld y2 = B * sinl(ra2);

    ld do1 = (ld)360.0 * ((ld)H/(ld)12.0) + ((ld)30.0*((ld)M/(ld)60.0));
    ld ra1 = do1 * ((ld)M_PI/(ld)180.0);
    ld x1 = A * cosl(ra1);
    ld y1 = A * sinl(ra1);

    cout << getSqrtl(x1,y1,x2,y2) << endl;
}

出力結果

4.56426

出力の条件として、以下を満たす必要があるため不正解となってしまう。 f:id:hakonebox:20200527214806p:plain

setprecisionマニピュレータを使う

混乱しながらたどり着いた解決策がsetprecisionを使うことでした。
浮動小数点数を出力する精度を設定できる。
下記の例では少数第20位まで出力している。

cout << fixed << setprecision(20) << getSqrtl(x1,y1,x2,y2) << endl;

出力結果

4.56425719433005553554

おまけ

一回setprecisionすると次の出力では使わなくてもその出力結果になった。

cout << getSqrtl(x1,y1,x2,y2) << endl;
cout << fixed << setprecision(20) << getSqrtl(x1,y1,x2,y2) << endl;
cout << getSqrtl(x1,y1,x2,y2) << endl;

出力結果

4.56426
4.56425719433005553554
4.56425719433005553554