ページ 11

デザイン定義での演算(div)の挙動について

Posted: 2017年6月07日(水) 15:03
by Dospec
どうしても解決できないのでご教授ください。

バージョン:1.2.3b

地元のグルメサイトを構築中なのですが、各お店から「最寄り駅(距離)」を表示させたくてスキーマでm単位で入力するようにして、
デザイン定義で演算してkmにしようとしたのですが、一部の数値を入力した場合に限り不明な小数値になって困っております。

スキーマ:

コード: 全て選択

<data name="DISTANCE" type="int" initdata="0" caption="ここまでの距離(m)" />
※もしかして文字列として処理すればうまくいくのかと思い、typeを「int」ではなく「text」、outputを「text1」「text2」「html1」「html2」に変えても同じ結果でした。

デザイン定義:

コード: 全て選択

<xsl:value-of select="round(DISTANCE div 100) div 10" />km
ほとんどの入力の場合こちらで問題ないのですが、例えば「9245」と入力すると、
「9.199999999999999km」と表示されます。当然「9.2km」となるようにしたいのですが不明です。

他にも
8800~
8700~
9800~
9700~
8200~
8300~
といった数値を入れても「*.*99999999999999km」と端数になります。

試しに、定数

コード: 全て選択

<xsl:value-of select="92 div 10" />km
と出力してみても「9.199999999999999km」と返されました。

除算として「div」を使うのは他のフォーラムでもありますし記述に問題はないかと思うのですが、
自己解決できず困惑しております。

当方のシステムのみで起こっている事象なのかだけでも知りたいです。

Re: デザイン定義での演算(div)の挙動について

Posted: 2017年6月08日(木) 13:03
by Dospec
おそらくJavascriptの浮動小数点での計算誤差の問題かと思うのですが・・・

とりあえず、こちらのCMSデザイナー内では計算処理を行なわず表示されたtextを外部のJavascript(jQuery)で計算処理すると「9.2」と意図してる結果が表示されました。

コード: 全て選択

$(function(){
	$(".fudo").each(function () {
        	var FUDO = $(this).text();
		$(this).text(Math.round(FUDO / 100) / 10);
	});
});
同じ計算をしているだけですが、なぜこちらでは「9.199999999999999km」と表示されて、
外部なら「9.2km」とできるのかは未だわかりません。
(※var FUDO = "9245";の場合)

Re: デザイン定義での演算(div)の挙動について

Posted: 2017年6月08日(木) 14:17
by webmaster
Deopecさん、ご質問ありがとうございます。

結論から先に書きますと、format-number関数を使ってみてください。

コード: 全て選択

<xsl:value-of select="format-number(round(DISTANCE div 100) div 10,'####0.0')" />km
format-number関数はXSLの標準関数で、数値データを整形して出力できる関数です。第二引数の'####0.0"で、整形フォーマットを指定しています。
format-number関数についてはこちらのページが参考になるかと思います。
https://msdn.microsoft.com/ja-jp/librar ... .120).aspx

なぜこのような事が起こるのかと言いますと、基本的にはコンピューターは小数の扱いが苦手で、常に「近似値」として処理を行っているからです。どのような環境でも、多かれ少なかれこの問題が発生します。
例えばJavascriptでも、

コード: 全て選択

alert( 9.2 * 100 );
を実行すると、920ではなく、
919.9999999999999
が表示されたりします。
CMS Designerが内部で使用している「XSLT」という技術においても同様ですが、処理方法や表示方法の違いが多少あり、今回のような違いが出ます。

しかし、一般的には、コンピューターで小数計算を扱う場合には、最終的に「数値整形関数(今回で言うとformat-number関数)」を用いて出力すると、安定した出力を得られるかと思います。

DospecさんはCMS Designerを非常に使いこなして下さっていて、とても嬉しいです。
この件に限らず、もしご不明な点がありましたら、また何なりとお申し付け下さい。

Re: デザイン定義での演算(div)の挙動について

Posted: 2017年6月08日(木) 16:18
by Dospec
webmaster 様
回答くださり誠にありがとうございました!
誰もが知ってるような常識的な質問なら恥ずかしいなぁと思っていましたが質問してよかったです!
でもよくある事象だったのですね!

こちらのフォーラムの「ファイルサイズを表示する方法」の説明の中では、
http://cms.al-design.jp/phpbb/viewtopic.php?t=140

コード: 全て選択

<xsl:value-of select="round(file1/@filesize div 102400) div 10" />
とだけ説明されており、format-number関数は登場してなかったのでこちら側に問題があるとばかり思っておりました。

小数点の計算には注意が必要!
format-number関数で囲って整形フォーマットを指定しておく!ですね!

教えていただいた通り修正して解決いたしました!

コード: 全て選択

<xsl:value-of select="format-number(round(DISTANCE div 100) div 10,'####0.0')" />km
CMSは他にもたくさんありますが、こちらのシステムのように出力側(HTML側)をここまで自由に作り込めるのに惚れて使ってみようと思いました!
まだ公開には至ってないですが、なんとか使いこなして完成させたいと思います!

本当にありがとうございましたー!

Re: デザイン定義での演算(div)の挙動について

Posted: 2017年6月08日(木) 18:13
by webmaster
Dospecさん、解決されたとのことで、ご報告ありがとうございます。

以前のwebmasterの投稿が、混乱を招いていたようで、申し訳ないです。
恐らくその頃のxsltライブラリでは、その書き方で問題なく動作していたものと思いますが、その後のxsltライブラリのアップデートに伴い、仕様が変更になっているようです。
この辺りまでフォローできておらず申し訳ありません。

ご指摘のトピックの方にも、こちらへ誘導するリンクを投稿しておきますね。
Dospecさんのように質問して頂ける方がいることで、こうして問題を共有できて、助かっております。

また、なんでもご質問頂ければと思います。

Re: デザイン定義での演算(div)の挙動について

Posted: 2017年6月21日(水) 17:50
by Dospec
webmaster様が変わっておられるんですね。

リンク誘導ありがとうございます。
今後ともよろしくお願いいたします。