LoginSignup
weemiee
@weemiee (weemiee)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【C言語】小数第◯位を四捨五入出来ない

Q&AClosed

標準入力された6つの整数値の平均値を算出し、四捨五入して小数第1位まで求めて結果を出力するプログラムについてです。

例:
平均の計算結果が56.739→出力値は56.7
平均の計算結果が56.789→出力値は56.8

プログラムは次のように作りました。

失敗したプログラム
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
	
	char buf[100];
	int a,b,c,d,e,f;
	
	fgets(buf,sizeof(buf),stdin);
	sscanf(buf,"%d %d %d %d %d %d",&a,&b,&c,&d,&e,&f);
	
	double ave = (a+b+c+d+e+f) / 6;
	int int_ave = (a+b+c+d+e+f) / 6;
	
	char str[100];
	snprintf(str,sizeof(str),"%1f",ave);   //aveを文字列に変換する
	
	char* p = strchr(str,'.');   //小数点の位置str[X]をつき止める
	if(p != NULL){
		if(str[(p-str)+2] >= 48 && str[(p-str)+2] <= 52){   //str[X] (小数点) の2個隣 (小数第2位) の文字が「0」~「4」だった場合
			int m = atoi(&str[(p-str)+1]);   //str[X] (小数点) の1個隣 (小数第1位) の文字を数値に変換して
			printf("%0.1f\n",int_ave+0.1*m);   //計算式:平均値の整数版+小数第1位の文字 (int) ×0.1 (1/10の位だから)
	    }else if(str[(p-str)+2] >= 53 && str[(p-str)+2] <= 57){   //str[X] (小数点) の2個隣 (小数第2位) の文字が「5」~「9」だった場合
			int n = atoi(&str[(p-str)+1]);   //str[X] (小数点) の1個隣 (小数第1位) の文字を数値に変換して
			printf("%0.1f\n",int_ave+0.1*(n+1));   //計算式:平均値の整数版+(小数第1位の文字 (int) に1を加えた (繰り上げた) 数字)×0.1 (1/10の位だから)
		}
	}
	
}

結果は失敗でした。コンパイルは出来たものの、期待した通りに出力されない上、小数点以下が0の一点張りになる等の問題に直面して困っています。

・(プログラムのコメント等をもとに)根本的に、僕の考え方が正しいか否か
・本当ならもっとシンプルに出来るプログラムを難しく考えていないかどうか(これが特に気になる)
・目的に合ったプログラムにするために、どこを訂正すべきなのか

上の2点について、アドバイス頂きたいです。

0

4Answer

とりあえず、すぐわかるミスを2つ。

sscanf(buf,"%d %d %d %d %d",&a,&b,&c,&d,&e,&f);  

で、%dが1つ足りないので5つの数値しか入力していません。

もう1つは、

double ave = (a+b+c+d+e+f) / 6;

int同士の割り算は結果もintです(小数部分は切り捨てられます)。
intをdoubleに代入しているだけなので当然小数部も0です。

double ave = (a+b+c+d+e+f) / 6.0;

のように除数をdoubleにしてあげれば計算結果もdoubleとなります。

1

シンプルに、math.h で定義されている cell()やfloor()を使うのはダメなんですかね?
任意の桁まで10で割っていって、0.5を足してintにキャストするという手もあるかと思います。

【C言語】四捨五入,切り捨て,切り上げする標準ライブラリ関数と自作関数【round/floor/ceil関数】
https://hiroyukichishiro.com/round-floor-ceil-in-c-language/

0

(mrbonjinさんのご指摘の箇所を直したあとで)printfに小数第1位までを出力するような書式を指定してはいかがでしょうか。

printf("%.1f\n", 56.739);  // 56.7
printf("%.1f\n", 56.789);  // 56.8
0

Comments

@gx3n-inueさん、@mrbonjinさん、@tuedaさん、ご回答ありがとうございます。
double型で計算したい時は、確かに型を揃えなければなりませんでしたね。仰る通りです。
また、出力フォーマット指定子を "%0.1f" から "%.1f" に変えただけでコードが片付いたのには驚かされました。単純に、僕の知識不足でした……。
とても勉強になりました。

0

Your answer might help someone💌