C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[15]: 数値型の書式指定


(過去ログ 46 を表示中)

[トピック内 23 記事 (1 - 20 表示)]  << 0 | 1 >>

■24424 / inTopicNo.1)  数値型の書式指定
  
□投稿者/ れい (764回)-(2008/09/03(Wed) 04:21:29)

分類:[.NET 全般] 

.Netの数値型に対するToStringと同じ機能を、一から自分でコーディングしました。
で、動作検証のために標準のToStringと比較していたのですが、
いくつか不思議なケースが見つかりました。

これらに関して何か情報がありましたら教えてください。


1 書式指定時の丸めに関して

ToStringで丸める必要がある場合は銀行丸めではなく四捨五入になっているようですが、
MSDN内に明記されていないようです。

Convertは銀行丸めなので、不思議な感じがあります。

(0.5R).ToString("0") -> "1"
(0.4R).ToString("0") -> "0"
Convert.ToInt32(0.4R) -> 0
Convert.ToInt32(0.5R) -> 0
Integer.Parse((0.5R).ToString()) -> 1


2 仮数部無しの指数表示に関して

(1).ToString("E+00") -> "E+00"
(10).ToString("E+00") -> "E+00"
(100).ToString("E+00") -> "E+00"
(1000).ToString("E+00") -> "E+00"

というように、表示されていない仮数部が1〜4の場合は指数部が0になるのですが、

(5).ToString("E+00") -> "E+02"
(50).ToString("E+00") -> "E+03"
(500).ToString("E+00") -> "E+04"
(5000).ToString("E+00") -> "E+05"

仮数部が5以上となると指数部が0で無くなります。

(1000).ToString("000E+00") -> "100E+01"
(1000).ToString("00E+00") -> "10E+02"
(1000).ToString("0E+00") -> "1E+03"

であることを考えると

(1000).ToString("E+00") -> "E+04"

が妥当かと思うのですが、
何か意味があるのでしょうか?

3 指数部の桁数

(10).ToString("0E+0000000000") -> "1E+0000000001"
(10).ToString("0E+00000000000") -> "1E+0000000001"
(10).ToString("0E+000000000000000000000") -> "1E+0000000001"

のように、指数部が10桁までしか表示されません。
これもUndocumentedでしょうか?

上記3点、何か情報をお持ちでしたら教えてください。
よろしくお願いします。
引用返信 編集キー/
■24428 / inTopicNo.2)  Re[1]: 数値型の書式指定
□投稿者/ やじゅ (600回)-(2008/09/03(Wed) 06:46:16)
やじゅ さんの Web サイト
No24424 (れい さん) に返信
> 1 書式指定時の丸めに関して
>
> ToStringで丸める必要がある場合は銀行丸めではなく四捨五入になっているようですが、
> MSDN内に明記されていないようです。
>

ゼロプレースホルダの説明なので違うかも知れませんが、近い整数側になるようです。

説明の誤り カスタム数値書式指定文字列
http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=652285&SiteID=7
引用返信 編集キー/
■24432 / inTopicNo.3)  Re[2]: 数値型の書式指定
□投稿者/ れい (766回)-(2008/09/03(Wed) 08:54:41)
No24428 (やじゅ さん) に返信
> ゼロプレースホルダの説明なので違うかも知れませんが、近い整数側になるようです。

MSDNの説明から最近接丸めを用いているのはわかるのですが、
その際の手法が載っていません。

最近接丸めは四捨五入(R丸め)か銀行丸めが一般的ですが、
その他にもたくさん方法があります。

.NetのToStringの場合はたぶん四捨五入のようなのですが、
MSDNに何もかかれていませんし、
Convertの場合は銀行丸めを採用しています。

なので、本当に四捨五入なのか少し不安なので確証が得たいというのと、
四捨五入であることに理由があるのなら、それが知りたいのですが。

引用返信 編集キー/
■24437 / inTopicNo.4)  Re[1]: 数値型の書式指定
□投稿者/ よねKEN (183回)-(2008/09/03(Wed) 09:26:53)


実験環境は何でしょうか?
・.NET FrameworkのバージョンやSP
・使用言語とコンパイラのバージョン

> (0.5R).ToString("0") -> "1"

RということはVBでしょうか?

実際に実験に使用したコードもそのまま検証できるものがあるとよいですね。


引用返信 編集キー/
■24439 / inTopicNo.5)  Re[2]: 数値型の書式指定
□投稿者/ ネタ好き未記入 (75回)-(2008/09/03(Wed) 09:28:44)
その辺はかなりカオスです。
言語ごとにポリシーが違いますし、数値関係の精度を求めるのならばFORTRANがベストだと思います。
引用返信 編集キー/
■24444 / inTopicNo.6)  Re[2]: 数値型の書式指定
□投稿者/ れい (768回)-(2008/09/03(Wed) 09:49:20)
No24437 (よねKEN さん) に返信
> 実験環境は何でしょうか?
> ・.NET FrameworkのバージョンやSP
> ・使用言語とコンパイラのバージョン

ああっと!
失礼しました。

.Net2.0 SP1(2.0.50727.1434)で、
Visual Studio 2005(8.0.50727.867)のVBとC#で試しました。

> 実際に実験に使用したコードもそのまま検証できるものがあるとよいですね。

そのままなんですが、こんな感じです。

        '丸めが不思議
        Debug.WriteLine((0.5R).ToString("0")) '-> "1"
        Debug.WriteLine((0.4R).ToString("0")) '-> "0"
        Debug.WriteLine(Convert.ToInt32(0.4R).ToString()) '-> "0"
        Debug.WriteLine(Convert.ToInt32(0.5R).ToString()) '-> "0"
        Debug.WriteLine(Integer.Parse((0.5R).ToString("0"))) '-> "1"

        '指数部の値が変
        Debug.WriteLine((1).ToString("E+00")) '-> "E+00"
        Debug.WriteLine((10).ToString("E+00")) '-> "E+00"
        Debug.WriteLine((100).ToString("E+00")) '-> "E+00"
        Debug.WriteLine((1000).ToString("E+00")) '-> "E+00"
        Debug.WriteLine((5).ToString("E+00")) '-> "E+02"
        Debug.WriteLine((50).ToString("E+00")) '-> "E+03"
        Debug.WriteLine((500).ToString("E+00")) '-> "E+04"
        Debug.WriteLine((5000).ToString("E+00")) '-> "E+05"
        Debug.WriteLine((1000).ToString("000E+00")) '-> "100E+01"
        Debug.WriteLine((1000).ToString("00E+00")) '-> "10E+02"
        Debug.WriteLine((1000).ToString("0E+00")) '-> "1E+03"
        Debug.WriteLine((1000).ToString("E+00")) '-> "E+04"

        '指数部の桁数が変
        Debug.WriteLine((10).ToString("0E+0000000000")) '-> "1E+0000000001"
        Debug.WriteLine((10).ToString("0E+00000000000")) '-> "1E+0000000001"
        Debug.WriteLine((10).ToString("0E+000000000000000000000")) '-> "1E+0000000001"


引用返信 編集キー/
■24447 / inTopicNo.7)  Re[3]: 数値型の書式指定
□投稿者/ よねKEN (184回)-(2008/09/03(Wed) 10:18:55)
No24444 (れい さん) に返信
> ■No24437 (よねKEN さん) に返信
>>実験環境は何でしょうか?
>>・.NET FrameworkのバージョンやSP
>>・使用言語とコンパイラのバージョン
>
> ああっと!
> 失礼しました。
>
> .Net2.0 SP1(2.0.50727.1434)で、
> Visual Studio 2005(8.0.50727.867)のVBとC#で試しました。

0.5の場合で確認しましたが、ソースコードの内容によってはコンパイラの
最適化等の関係もあるかと思ったのですが、ILまではそのまま0.5が渡ってますね。
というわけで、コンパイラは関係なさそうです。

で、純粋にToStringメソッドの内部の問題ということになるわけですが、
ソースを追ってもわかりませんでした。
Double.ToString(Double.cs)でNumber.FormatDouble(Number.cs)を呼んでいますが、
このメソッドはC#のソース上にはなく外部の関数のようで、そこで手がかりがなくなりました。
Numberクラスには各書式の説明(英語)がありますが、丸めのルールについては明記されていないようです。



引用返信 編集キー/
■24448 / inTopicNo.8)  Re[4]: 数値型の書式指定
□投稿者/ ネタ好き未記入 (76回)-(2008/09/03(Wed) 10:32:07)
2008/09/03(Wed) 10:41:03 編集(投稿者)
2008/09/03(Wed) 10:39:33 編集(投稿者)

ひとつ気になるのですが、IFormattableインタフェースを引数に取るToString()メソッドは試しましたか?
自分で制御する場合はFormatter系オブジェクトを指定するのが.NETの考え方だと思います。

追記
挙動そのものについてですが、
System.Sigle(IEEE 754) 規格に準拠、
他にも値の扱い一般に関して、IEEE Standard for Binary Floating-Point Arithmetic」(http://www.ieee.org/portal/index.jsp)がヒントになると思います。
引用返信 編集キー/
■24528 / inTopicNo.9)  Re[5]: 数値型の書式指定
□投稿者/ れい (769回)-(2008/09/03(Wed) 19:29:59)
No24447 (よねKEN さん) に返信
> Numberクラスには各書式の説明(英語)がありますが、丸めのルールについては明記されていないようです。

確認しました。
やっぱり明記されていないようです。

IEEE754規格では「銀行丸めを既定とすべき」ということになってるはずですが…
常識の範囲内ということでしょうか。

No24448 (ネタ好き未記入 さん) に返信
> ひとつ気になるのですが、IFormattableインタフェースを引数に取るToString()メソッドは試しましたか?

試しました。
小数点記号とかは変更されますが、上記の問題点に関しては変わりませんでした。

> 他にも値の扱い一般に関して、IEEE Standard for Binary Floating-Point Arithmetic」(http://www.ieee.org/portal/index.jsp)がヒントになると思います。

http://ieeexplore.ieee.org/iel1/2355/1316/00030711.pdf?tp=&isnumber=1316&arnumber=30711
も読んでみましたが、
文字列への変換の際の指針は書かれていませんでした。

適当ってことですかねぇ…
引用返信 編集キー/
■24529 / inTopicNo.10)  Re[6]: 数値型の書式指定
□投稿者/ ネタ好き未記入 (83回)-(2008/09/03(Wed) 19:34:30)
No24528 (れい さん) に返信
そうですか・・・
マイクロソフトのドキュメントのあれは有名な話しですので、おそらくまたやってしまったのでしょう。
ソースを読んでみてはいかがでしょうか?
もしかしたらコメントに書いているかもしれません。
引用返信 編集キー/
■24532 / inTopicNo.11)  Re[7]: 数値型の書式指定
□投稿者/ れい (771回)-(2008/09/03(Wed) 19:39:21)
No24529 (ネタ好き未記入 さん) に返信
> ■No24528 (れい さん) に返信
> そうですか・・・
> マイクロソフトのドキュメントのあれは有名な話しですので、おそらくまたやってしまったのでしょう。

えっと、「あれ」とは何でしょう?
教えてください。

> ソースを読んでみてはいかがでしょうか?
> もしかしたらコメントに書いているかもしれません。

よねKENさんも言っていたので
私もダウンロードして読んでみましたが、
肝心の部分が提供されてるソースの範囲外になってしまっていました。

MONOも読んでみましたが、
なんか微妙に振る舞いが違うようです。

引用返信 編集キー/
■24533 / inTopicNo.12)  Re[8]: 数値型の書式指定
□投稿者/ ネタ好き未記入 (85回)-(2008/09/03(Wed) 19:47:47)
No24532 (れい さん) に返信
あれというのは、隠蔽主義と言っていいのやら、宣伝を一色単にしているというのか・・・
実例を挙げると、Int32型を単純にしたいがために数多くのメソッドをマニュアルから隠蔽し、
それには飽き足らず止めにインターフェイス実装にしてしまったそうです。
そんな事すればパフォーマンスが悪くなるし混乱をうむのは目に見えています。
そういったいけない行為をマイクロソフトは何度かしています。
引用返信 編集キー/
■24534 / inTopicNo.13)  Re[9]: 数値型の書式指定
□投稿者/ NyaRuRu (61回)-(2008/09/03(Wed) 19:52:52)
No24533 (ネタ好き未記入 さん) に返信
> 実例を挙げると、Int32型を単純にしたいがために数多くのメソッドをマニュアルから隠蔽し、
> それには飽き足らず止めにインターフェイス実装にしてしまったそうです。
> そんな事すればパフォーマンスが悪くなるし混乱をうむのは目に見えています。
> そういったいけない行為をマイクロソフトは何度かしています。

意味がよく分からないんですが,[要出典]ということでお願いします.
引用返信 編集キー/
■24536 / inTopicNo.14)  Re[10]: 数値型の書式指定
□投稿者/ ネタ好き未記入 (86回)-(2008/09/03(Wed) 20:01:37)
No24534 (NyaRuRu さん) に返信
原文があまりにも長い文章なのではしょっていまいました。ごめんなさい。
この出典は確かプログラミング.NET Framework第1版だと思います。

端折りすぎたのでもっと詳しく書きます。

.NET1.0が発売される前、開発者用SDKではInt32などの値型は、色々なメソッドが定義されていたそうです。
しかし、マーケティング的にマイクロソフトは、Int32などの【単純型】がちっとも単純じゃない事が問題だと判断したそうです。そこで、まずはマニュアルから一々Int32が備えるメソッドの記述を削除しました。
そうすると、開発版を試した開発者が当然混乱したそうです。
それで困ったマイクロソフトは、今度はインタフェースを定義して、そのインターフェイスにメソッドを定義する事にして、Int32の「多いメソッドをインターフェイスの明示化で実装しなおした」そうです。
この話しはプログラミング.NET Frameworkの作者のキャリアを考えると真実だと思います。
実際に私は.NET1.0当時、あるはずのメソッドがMSDNに記載されていない事を確認しました。
そういった、マーケティングがらみの話とか、コーディングルールを車内で守れないなどの【組織的な問題】が存在するそうです。
超巨大企業は大変ですね。
引用返信 編集キー/
■24538 / inTopicNo.15)  Re[11]: 数値型の書式指定
□投稿者/ NyaRuRu (62回)-(2008/09/03(Wed) 20:09:22)
2008/09/03(Wed) 20:10:28 編集(投稿者)

No24536 (ネタ好き未記入 さん) に返信
> 実際に私は.NET1.0当時、あるはずのメソッドがMSDNに記載されていない事を確認しました。

ではいま MSDN Library と Int32 のメタデータを確認されてみてはいかがでしょうか?
私には,Int32.IConvertible.* 以外にインターフェイスの明示的実装を確認できませんでした.
問題にされているのはこれらのメソッドのことですか?
これらのメソッドが public であるべきだとお考えなのでしょうか?

# 本題から外れてすみません
引用返信 編集キー/
■24539 / inTopicNo.16)  Re[11]: 数値型の書式指定
□投稿者/ ネタ好き未記入 (88回)-(2008/09/03(Wed) 20:09:25)
れい さん に返信
説明足らずだったので前の説明に補足します。
海外ではFORTRAN.NETが存在するそうです。
科学技術用言語がこのような状態でそのまま放置するわけがありません。
独自ライブラリを持つ、コンパイラで対処する(MSILレベルの対処)、などの何らかの対処をしていると思います。
その辺が参考になると思います。
引用返信 編集キー/
■24548 / inTopicNo.17)  Re[11]: 数値型の書式指定
□投稿者/ れい (772回)-(2008/09/04(Thu) 00:06:31)
2008/09/04(Thu) 00:06:56 編集(投稿者)

No24536 (ネタ好き未記入 さん) に返信
> そういった、マーケティングがらみの話とか、コーディングルールを車内で守れないなどの【組織的な問題】が存在するそうです。
> 超巨大企業は大変ですね。

たかが書式指定文字列の話をMSの内部構造とその問題まで結びつけるのは非合理だと思いますよ。
論理が飛躍しすぎ、演繹しすぎかと。

まぁ私はMSの内部に興味はありません。
それよりもDocumentedかどうか、皆さんの常識に照らして普通か、異常かを知りたいです。

「丸め」は実用上の問題で(0.5が0に丸められて1.5が2に丸められるとびっくりする人がいるのかな?)、
指数の問題は実質的にあまり影響ない部分なので、適当なのかもしれません。

バグというわけでもないですし、私も全く困らないので、
とりあえず解決にします。

ありがとうございました。
なにか関連した情報がありましたら教えてください。

解決済み
引用返信 編集キー/
■24554 / inTopicNo.18)  Re[12]: 数値型の書式指定
□投稿者/ ネタ好き未記入 (90回)-(2008/09/04(Thu) 09:05:28)
NyaRuRu さんに返信
まずはじめに私が言っていたメソッドはIConvertibleメソッドである事を明記しておきます。
現在のMSDNを調べてみたところ載っていました。これは素直によかったと思います。
「ドキュメント隠蔽」されるのはたまったものではありません。
次に現在のIConvertibleメソッドを確認しました。
おっしゃる通りで確かにPrivateで明示的に実装されています。
これをPublicにすればいいかどうかについては、個人的にはPublicかつ非明示的実装がよかったと思います。
これがPublicでなかったのはパフォーマンス上の理由から賢明だとは思うのですが、型変換を隠蔽する意味がわかりませんから、明示的実装によりボックス化するのを止めてもらって、Publicに型変換させてほしいと思います。
Convertクラスを経由するよりも、Int32等のメソッドから直接呼び出したいです。
それに何よりも「隠蔽」が嫌いです。開発者をもっと信じてほしいものです。
まぁ、使用する開発者の数を考えると、マイクロソフトの気持ちもわからないわけではないですが・・・

なお、この情報源はプログラミング.NET Framework第1版P344です。
それによると、他にも「ドキュメント隠蔽」した型があるそうです。
情報処理技術者は情報が命ですから、そのような行為は情報源であるマイクロソフトにして欲しくないです。
解決済み
引用返信 編集キー/
■24565 / inTopicNo.19)  Re[12]: 数値型の書式指定
□投稿者/ みきぬ (64回)-(2008/09/04(Thu) 10:20:05)
2008/09/04(Thu) 11:12:39 編集(投稿者)

なんか自分がものすごーくずれた発言してるような気がしてきたので削除(。。;
解決済み
引用返信 編集キー/
■24566 / inTopicNo.20)  Re[13]: 数値型の書式指定
 
□投稿者/ ネタ好き未記入 (92回)-(2008/09/04(Thu) 10:45:23)
れい さん に返信
ネットを探してライブラリを探すというのは如何でしょうか?
科学者にとって数値の精度は重要、かなりの確率で誰かが「ドキュメント付きで」作っていると思います。
解決済み
引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -