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

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

新規登録して質問してみよう
ただいま回答率
85.46%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

1451閲覧

10進数の小数をN進数に変換する方法

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2020/05/09 08:26

前提・実現したいこと

Cで10進数の小数をN進数に変換するプログラムを作っています。

発生している問題・エラーメッセージ

Nを2にするときには
.0011110101110000101000111101011100001010001111010111
と正解が出るのですが、
Nを5にするときには
.1044444444444444444…
と正解が出ません(正解は.11)。

該当のソースコード

C言語

#include <stdio.h>

int main(void){
int K = 0;
double R = 0.24; //実数
int N = 5; //N進数
printf(".");
while(R != 0){
K = R * N;
printf("%d", K);
R = R * N - K;
}
}

試したこと

K = (int)(R * N)のようにキャストをつかったが結果は改善しませんでした。

補足情報(FW/ツールのバージョンなど)

paiza.ioを使用

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2020/05/09 08:48

> Nを5にするときには > .1044444444444444444… > と正解が出ません(正解は.11)。 これ正解じゃないの? .11 と .104444444444444 の差は 0.00000000000000... つまり 0 だから同じじゃん。
退会済みユーザー

退会済みユーザー

2020/05/09 09:08

なるほどそういわれるとわかりやすいです。
guest

回答3

0

考えかたの案だけを述べます。

 double や float での計算では誤差がつきまといます。
この問題では、
小数点をなくして、long int で計算してから 小数点を戻す
ようにしてはどうでしょうか?

0.24 (10進) を 125 倍 (125 = 5 ** 3) 倍すれば 30 (10進) です。
30 (10進) は 11 (5進) です。
小数店を戻すには 125 (10 進) で割ることがになります。
5 進数では 125 で割ることは小数点を左に 2 つ移動することです。
したがって 0.11 (5進) となります。

与えられた 小数点を含む 10 進の小数を 5倍、 25倍, 125 倍. 5 ** 4 倍, 5 ** 5 倍 ... としていき、小数がなくすようにしてから、10 進 -> 5 進変換をし、
その結果を元に戻す ( 5 ** n 倍していたなら、n 個だけ小数点を左にずらす)
というようにすれば 計算誤差なく計算できます。
5 ** n 倍をいつまでしても小数をなくすことができなければ、その数は循環小数になるということです。
狄道なところで 5 ** n 倍すすのをやめ, 小数点以下を切り上げるか、切り上げて計算をするしかありません。

投稿2020/05/10 00:44

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/05/10 14:42

参考にさせていただきます。
guest

0

その結果であってますよ

PCの内部では2進数で数値表現します。
あなたの扱う10進数からの2進数へ変換する段階で、誤差が入ります
#0.24という数値は表現できません
なので、結果はそのように。

投稿2020/05/09 08:37

y_waiwai

総合スコア87800

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

C

1double R = 0.24; //実数

C言語の浮動小数点数は、通常2進法で実装されているため、この時点で誤差を含みます。厳密にやりたいのであれば、整数演算だけで構築するようにしましょう。

投稿2020/05/09 08:36

maisumakun

総合スコア145208

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問