ページ 11

小数の桁数を指定した切捨ての仕方

Posted: 2008年2月22日(金) 13:49
by たか
こんにちは、いかについて質問です。

double aaa = 123.456779874243753

上記のaaaを小数点第6位以下を切捨てる。

結果 123.45677

上記方法を教えてください。
環境はvisual studio 2005 .net です。

以下は試したところ誤差が出てしまったので、できれば誤差の出ない切捨て方法をお願いします。

long box = aaa * 100000;
aaa = box / 100000;

Re:小数の桁数を指定した切捨ての仕方

Posted: 2008年2月22日(金) 13:57
by 組木紙織
質問1:
 言語はcですか?c++ですか?
質問2:
 切り捨てした結果はどうするのですか?(変数に代入するとか、表示するとか)

Re:小数の桁数を指定した切捨ての仕方

Posted: 2008年2月22日(金) 14:11
by たかぎ
> 誤差が出てしまったので

この場合は「誤差」とはいわないような...
long box = aaa * 100000; 
aaa = box / 100000;
で多少はましになりますが、誤差が全くなくなるわけではありません。

10進法で表現して誤差がないようにするには、BCD演算でも行うとか、文字列で扱うとかしないとダメです。

Re:小数の桁数を指定した切捨ての仕方

Posted: 2008年2月22日(金) 14:31
by たかぎ
すみません。コピペのミスです。
long box = aaa * 100000; 
aaa = box / 100000.0;
でましになります。

Re:小数の桁数を指定した切捨ての仕方

Posted: 2008年2月22日(金) 14:56
by たか
質問1:
 言語はcですか?c++ですか?

回答1:
 C++です。

質問2:
 切り捨てした結果はどうするのですか?(変数に代入するとか、表示するとか)

回答2:
 関数の戻り値として返します。(変数に代入)



前回の質問(標準関数atofについて:2008/02/17(日) 10:32)
の続きになってしまうのですが…以下が現在の状況です。

#######################################################

moji    :char型の配列で"123.45678901234567"が格納
ret  :double型
box :long型

/* char → double */
ret = atof(moji);

■ret = 123.45678901234567(ウォッチウインドウ表示)

box = ret * 100000;

■box = 12345678(ウォッチウインドウ表示)

ret = box;
ret /= 100000.0;

■ret = 123.45677999999999(ウォッチウインドウ表示)

####################################################

期待値 ret = 123.45678

うまく伝えられなくすいません。

Re:小数の桁数を指定した切捨ての仕方

Posted: 2008年2月22日(金) 15:24
by 組木紙織
つまり
double ret = 123.45678901234567;
定義した retの
小数点以下8桁までを表示したいということですか?

切り捨てる関数を double kiri(double)として

double ret2 = kiri(ret);

//ret2を演算に使う。
ret2 =0.5+ret2

という風にしたいわけではなく。

ならこちらでも。
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>

int main()
{
	double ret = 123.45678901234567;
	std::ostringstream stream ;
	stream <<std::setprecision(10) << ret;
	
	std::string out;
	out.assign(stream.str(),0,9);
	std::cout << out << std::endl; 
	
	return 0;
}

Re:小数の桁数を指定した切捨ての仕方

Posted: 2008年2月22日(金) 15:30
by バグ
あら?C++でしたか…
まぁ、せっかくCで組んでみたので、一応載せておきます(^_^;)
結構、力技なのであまり参考にはならないと思いますが…
int main(void)
{
	double aaa = 123.456779874243753;
	char str[512], *pchr;

	// 一度文字列に変換
	sprintf(str, "%.16f", aaa);

	// 文字列内に小数点がある場合は小数点以下6桁目を'\0'に置き換える
	if ((pchr = strchr(str, '.')) != NULL)
		*(pchr + 6) = '\0';

	// 文字列を数値に戻して画面に表示する
	aaa = atof(str);
	printf("%.5f\n", aaa);

	return 0;

Re:小数の桁数を指定した切捨ての仕方

Posted: 2008年2月22日(金) 15:43
by たか
サンプル回答ありがとうございます。

参考にした結果ですが
小数点位置を戻す前にあらかじめ
小さな数を足してから処理するようにしました。

ret += 0.0000005;
ret /= 100000.0;

■ret = 123.45678000000500(ウォッチウインドウ表示)

ご協力ありがとうございました。

Re:小数の桁数を指定した切捨ての仕方

Posted: 2008年2月22日(金) 15:56
by バグ
それだと『切捨て』ではなくて、『四捨五入』もしくは『繰上げ』になってしまいませんか?

外部シンボルが未解決?

Posted: 2008年3月21日(金) 00:11
by ぬっち
こんばんは、また詰まってしまったので質問させていただきますm(--)m

シューティングゲームの館の第8節にて、サンプルをコピペしてプログラムを実行してみたところ、エラーが発生しました。(ちなみにBCC Developerを使っています)
「プロジェクトの設定」-「アプリケーション」-「ターゲット」をコンソールアプリケーションにしたところ
Error: 外部シンボル '_main' が未解決
と出てしまい、
Windowsアプリケーションとしたところ、
Error: 外部シンボル '_img_player_shot' が未解決
Error: 外部シンボル '_PlayerShot' が未解決
と出てしまいました。

過去ログを見て、externをWinmain外に出しても何ら変化がありませんでした。
改善すべき点と、アプリケーションの使い分け方を教えていただけないでしょうか?

よろしくお願いします。

Re:外部シンボルが未解決?

Posted: 2008年3月21日(金) 09:04
by バグ
コンソールアプリケーションを指定したのならば、Winmain関数ではなく、main関数を使用して下さい。

Re:外部シンボルが未解決?

Posted: 2008年3月21日(金) 23:03
by ぬっち
バグさん返答ありがとうございます。

無事解決しました^^