double型とfloat型について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
masuter

double型とfloat型について

#1

投稿記事 by masuter » 8年前

コード:

#include <stdio.h>

#define PI 3.14159;

float Circle_S(float r) {
	if (r < 0) {
		return -1;
	}
	float result1 = 0;
	result1 = r*r*PI;
	return result1;
}
float Circle_L(float r) {
	if (r < 0) {
		return -1;
	}
	float result2 = 0;
	result2 = r * 2 * PI;
	return result2;
}
int main() {
	float radius = 0;
	float result1 = 0;
	float result2 = 0;
	printf_s("半径を入力してください(cm)\n>");
	scanf_s("%f", &radius);
	result1 = Circle_S(radius);
	result2 = Circle_L(radius);
	if (result1 < 0 || result2 < 0) {
		printf_s("正しい値を入力してください\n");
	}
	printf_s("面積S = %f(m^2) \n\n円周L = %f(cm)\n\n\n\n", result1, result2);
	return 0;
}
これをビルドすると以下のような警告をされました。どうやって修正すればいいですか?
課題2-2.c(10): warning C4244: '=': 'double' から 'float' への変換です。データが失われる可能性があります。
課題2-2.c(18): warning C4244: '=': 'double' から 'float' への変換です。データが失われる可能性があります。

かずま

Re: double型とfloat型について

#2

投稿記事 by かずま » 8年前

masuter さんが書きました:どうやって修正すればいいですか?
修正方法は、#define 3.14159; の ; を f に変える。

そもそも ; を付けるのが間違い。
; が付いていると、10行目は
 result1 = r*r*3.14159;;
となり、これは
result1 = r*r*3.14159; と ; の 2つの文と解釈され、
2つ目の ; が空文なので、エラーにならないだけ。
もしも 10行目が
 result1 = PI * r * r;
だったら、
 result1 = 3.14.159; * r * r;
となって、* r * r; がエラーになります。

「#define PI 3.14159 を変更してはならない」という条件があるのなら
10行目を
 result1 = r * r * (float)PI;
とすればよい。18行目も同様。

では、なぜこれらの修正でよいのかを調べて説明してください。

かずま

Re: double型とfloat型について

#3

投稿記事 by かずま » 8年前

かずま さんが書きました:  result1 = 3.14.159; * r * r;
3.14.159 は、3.14159 の間違いです。すみません。
かずま さんが書きました: では、なぜこれらの修正でよいのかを調べて説明してください。
これらとは、
  1. 3行目を #define PI 3.1459f にすること
  2. 10行目と 18行目の PI の前に (float) をつけること
result1 = r * r * 3.14159 という式において、
r は float ですから r * r の計算結果も float です。
3.14159 は double です。
(r * r) * 3.14159 は、float * double という異なる型の掛け算です。
この場合、(r * r) は double に変換されます。
そして、(r * r) * PI の計算結果は double になります。

次に、result1 は float です。
double の精度は 10進で約16桁。
float の精度は、10進で約7桁。
double の値を float の変数に代入すると、桁落ちが起こることがあります。

例えば、r が 2.75 の場合、r * r は 7.5625
7.5625 * 3.14159 は 23.7582744
double ではこの値を保持できますが、
float の変数に代入すると、23.75827xx なって値が変わってしまいます。

そのため、「データが失われる可能性があります。」という警告(warning)が
出ているのです。これは警告であってエラーではありません。

3.14159f または 3.14159F と書けば、それは float ですから、
r * r * 3.14159f の計算結果も float になって、警告は出なくなります。

また (float)3.14159 は、キャスト(明示的な型変換) により float に
なるので、r * r * (float)3.14159f の計算結果も float になります。

かずま

Re: double型とfloat型について

#4

投稿記事 by かずま » 8年前

すみません。訂正です。
かずま さんが書きました:これらとは、
  1. 3行目を #define PI 3.1459f にすること
  2. 10行目と 18行目の PI の前に (float) をつけること
「3.1459f にすること」は
「3.14159f にすること」の間違いです。
かずま さんが書きました: また (float)3.14159 は、キャスト(明示的な型変換) により float に
なるので、r * r * (float)3.14159f の計算結果も float になります。
「r * r * (float)3.14159f」は
「r * r * (float)3.14159」の間違いです。

回答が理解できたら、解決にチェックをつけて返信してください。
解らないところがあれば、放置せずに質問してください。
他の質問も同様です。

返信

“C言語何でも質問掲示板” へ戻る