質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.64%

C++ 小数500桁の全ての文字列を得る方法はありますか?

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,106

opyon

score 991

解決!

回答くださった方ありがとうございました。

参考情報:多倍長浮動小数点数

@tiitoiさんの回答より

#include <boost/multiprecision/cpp_dec_float.hpp>

namespace mp = boost::multiprecision;
// 仮数部 500 bit の浮動小数点数
using cpp_dec_float = mp::number<mp::cpp_dec_float<500>>;

知りたいこと

タイトルのとおりですが、例えば1/7=0.1428571428571428...
これを全て文字列として小数点以下500桁欲しいのですがSTLのlong double型ですと正確な値は16桁までしか取得できません。
何か良い方法があればご教示頂けると助かります。

サンプルコード

#include <cstdio>
#include <iostream>
#include <iomanip>

int main()
{
    long double x;
    for (int i = 1; i < 10; ++i)
    {
        x = 1.0 / i;
        std::cout << i << " " << std::fixed << std::setprecision(20) << x << std::endl;
    }
    getchar();
    return 0;
}
// 出力例
// 1 1.00000000000000000000
// 2 0.50000000000000000000
// 3 0.33333333333333331483
// 4 0.25000000000000000000
// 5 0.20000000000000001110
// 6 0.16666666666666665741
// 7 0.14285714285714284921
// 8 0.12500000000000000000
// 9 0.11111111111111110494
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

小数点以下500桁欲しい

浮動小数点数の桁数は、仮数部のビット数で決まります。
IEEE754 という規格で単精度 (C++ の float 型) では23ビット、倍精度 (C++ の double 型) では52ビットと決められています。

log_10 2^23 = 6.923689900271567
log_10 2^52 = 15.653559774527022

では、10進50桁を表すのに2進で何ビット必要なのか考えると、1661 ビットあればいいことがわかります。(ケチ表現で1660ビット)

log_{10} 2^x = 500
2^x = 10^{500}
x = log_2{10^{500}} = 1660.96404...

 boost::multiprecision

boost の multiprecision ライブラリで多倍長浮動小数点演算が行えます。

以下で仮数部を指定したビット数の浮動小数点数を作成できます。

mp::number<mp::cpp_dec_float<ビット数>>

基数は10なので、500桁表したい場合はそのまま500とすればよいです。
ただし、ケチ表現により実際はビット数 + 1 桁を表すことができます。

#include <iostream>

#include <boost/multiprecision/cpp_dec_float.hpp>

namespace mp = boost::multiprecision;
// 仮数部 500 bit の浮動小数点数
using cpp_dec_float = mp::number<mp::cpp_dec_float<500>>;

int main()
{
    cpp_dec_float a = 1.;
    cpp_dec_float b = 7.;
    cpp_dec_float result = a / b;

    // 桁数
    std::cout << "digits: "
              << std::numeric_limits<decltype(result)>::digits10 + 1
              << std::endl;
    // 値
    std::cout << std::setprecision(
                     std::numeric_limits<decltype(result)>::digits10 + 1)
              << result;
}
digits: 501
0.14285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714285714

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/02 13:13

    回答ありがとうございます。
    質問に書こうか迷っていたのですが、また別質問になるので敢えて要件だけにして質問していました。
    boostのリファレンスにある下記を実装してエラーで躓いて利用を断念していました。
    mpfr_float_500 仮数部が500ビットの浮動小数点数型

    cpp_dec_floatの方を使って定義すれば良かったのですね。
    実装例をサンプルコードで提示して頂けたのでどのように使うかの理解が深まりました。

    キャンセル

  • 2018/11/02 13:20

    mpfr_float は外部ライブラリ MPFR library を使うものなので、使うにはそちらを導入しておく必要があります。
    cpp_dec_float は boost::multiprecision の実装を使うので、外部ライブラリなしに使えます。

    キャンセル

  • 2018/11/02 13:23

    なるほど!そういうことでしたか!
    使えないものを使おうとしていたのですね^^;
    これまた理解が深まりましたありがとうございます。

    キャンセル

+1

筆算の方法で計算すればいいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/02 13:37

    念のため。高速計量というのはあくまで「実用上問題になることはないであろう」ということで、boost::multiprecision と比較したことはありません。

    キャンセル

  • 2018/11/02 13:38

    >効率が悪くなるならデメリットですが、そうでないなら愚直を恐れる必要はありません
    目からウロコです!
    愚直を恐れず、ライブラリに頼らず(多分頼る)、精進します。

    キャンセル

  • 2018/11/02 13:39

    >高速計量というのはあくまで「実用上問題になることはないであろう」
    お気遣いありがとうございます。
    問題を解くレベルの実装ですので大丈夫です。

    キャンセル

+1

500桁分の数値の配列から10進演算するクラスを作りましょう
加減乗除を実装する必要はありますが、そんなに難しくはないですよ

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/02 13:15

    回答ありがとうございます。
    そもそもある桁数以上の桁が取り出せないのです。

    キャンセル

  • 2018/11/02 13:18

    まあ、拡張した浮動小数点使うのもいいですが、10進<>2進の変換のところで満足できないところがでてきそうなきがします

    キャンセル

  • 2018/11/02 13:26

    取り敢えず1000桁必要な問題まで解けたので今回の要件では大丈夫そうです。
    速度重視とかまた別の条件や要件があるとクラス実装なども考慮する必要が出てくるかも知れませんね。
    その時はまた質問させていただきたいと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る