[過去ログ] Visual Studio 2008 Part 22 (314レス)
1-

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
176: 2018/09/14(金)21:39 ID:fXySkelb(1) AAS
再現するコードをみないとなにもわかるわけがない
低学歴知恵遅れが書くコードなんかなにをやってるか分からないからな

ごちゃごちゃいってないで再現するコードをあげなさい
177
(1): 2018/09/15(土)06:26 ID:/OsufeBT(1) AAS
月並みな意見だけど、
「症状を再現できる最小のソースと初期データ、それとコンパイル環境」
まで切り詰めてみるのが早道じゃないかな。

ちょくちょく発生する事例なら、解決策を知ってる誰かが教えてくれてるかと。
週末、より多くの人が質問を見ることを期待して待つ手もあるけど。
178: 2018/09/15(土)08:56 ID:9ZmI9OgI(1) AAS
より基本に立ち返ろう
そもそも誤差はあるのか?

計算結果を何を使ってどう出力しているかだけでもソースを見せてくれ
179: 2018/09/15(土)13:36 ID:heijdb7v(1/7) AAS
>>174
x87でも誤差を丸める方法を fpu control word で設定できる事は出来る。
四捨五入と切り捨てなどを切り替えられる。
180: 2018/09/15(土)13:42 ID:heijdb7v(2/7) AAS
fpu control word で、丸め方法と、精度の二つを独立に設定できる。

この精度の設定で、メモリ上の表現がdouble型でも、計算時のfpuの内部精度が変わってくる。

普通は64bit doubleに対して、fpu内部では80bitの精度で計算する。仮数部のbit数は、確か、それぞれ、53BIT、64BITだったかな。
181
(1): 2018/09/15(土)14:05 ID:heijdb7v(3/7) AAS
Intel® 64 and IA-32 Architectures Software Developer’s Manual

[Vol 1]

11.6.8 Compatibility of SIMD and x87 FPU Floating-Point Data Types

SSE and SSE2 extensions operate on the same single-precision and double-precision floating-point data types that
the x87 FPU operates on. However, when operating on these data types, the SSE and SSE2 extensions operate on
them in their native format (single-precision or double-precision), in contrast to the x87 FPU which extends them
to double extended-precision floating-point format to perform computations and then rounds the result back to a
single-precision or double-precision format before writing results to memory. Because the x87 FPU operates on a
higher precision format and then rounds the result to a lower precision format, it may return a slightly different
result when performing the same operation on the same single-precision or double-precision floating-point values
省2
182
(1): 2018/09/15(土)14:14 ID:heijdb7v(4/7) AAS
>>181
書いてある意味は、

「SSEやSSE2だと、float(32BIT)やdouble(64BIT)のまま計算するが、x87 fpuだと、もっと高い精度であるところの
  『double extended-precision floating-point format(拡張倍精度浮動小数点フォーマット:80BIT)』
で計算を実行して、丸めてから、floatやdoubleに戻す。
そのため、SSE/SSE2 と x87 fpuでは結果が変わることがある。
しかし、その場合でも結果の違いは、仮数部の LSB (最も価値の小さいBIT)の1BITにだけ現れる。」

というような事。
183
(2): 2018/09/15(土)16:09 ID:aC3C7hdp(1/2) AAS
揚げ足取りだけどLSBを「最も価値が小さい」って直訳はいかがなものかなw
普通に最下位ビットじゃないの?

ところで
> the least-significant bits
これ何で複数形なのかね
184: 2018/09/15(土)16:14 ID:AVfR6YnT(1) AAS
2の0乗だから実際価値が低い

上はMVBで
185: 2018/09/15(土)17:07 ID:UR1d6CKz(1/5) AAS
>>182
ありがとう。
ただ一応それは知ってて、その上で、IDEの環境設定等を疑っている。

>>177
とはいえ地道に辿って、同様の再現コードを作ることに成功しそうだ。
もう少し調べて、多分今晩か明日午前中に上げる。
186
(1): 2018/09/15(土)17:12 ID:heijdb7v(5/7) AAS
>>183
「The difference occurs only in the least-significant bits of the significand.」

これは、SSE の場合の LSB と、x87 FPU の場合の FPU の2種類を頭の中に想定していると思われる。

SSE: a1 = 1.xxxxxxxxz * 10^b
x87 : a2 = 1.yyyyyyyyw * 10^c

つまり、LSB は、↑のように、z と w で、2つあるので、LSBs という英語になる。
187: 2018/09/15(土)17:15 ID:heijdb7v(6/7) AAS
誤:これは、SSE の場合の LSB と、x87 FPU の場合の FPU の2種類を
正:これは、SSE の場合の LSB と、x87 FPU の場合の 2種類を
188: 2018/09/15(土)17:18 ID:heijdb7v(7/7) AAS
>>183
>揚げ足取りだけどLSBを「最も価値が小さい」って直訳はいかがなものかなw
>普通に最下位ビットじゃないの?

整数の場合は、「最下位ビット」というと、本当にBITの位置が一番右にあるようなイメージもある。

一方、浮動小数点数の場合は、右にあるとかより、仮数部において、一番価値の小さいビット、というニュアンスを使えたかった。

IEEEでは、それは確かに一番右にあるビットであって、マシン語レベルの表現では、BIT0ではあるのだが。

ニュアンス的に。
189: 2018/09/15(土)17:29 ID:aC3C7hdp(2/2) AAS
>>186
それは俺も思ったけど、それならsignificandの方も複数じゃないとおかしいような...
190
(1): 2018/09/15(土)20:35 ID:UR1d6CKz(2/5) AAS
同様の症状を再現出来るようになったので上げる。
完全再現は出来てないが、使い物にはなるはず。興味がある人はよろしく。

症状:
単独で起動した場合と、IDEから起動した場合で、結果が異なる。

環境:
VS++2008ExpressEdition

再現方法:
1. 新規プロジェクトを作成。(CLRコンソールアプリケーション。オプション等は全てデフォのまま)
2. mainを以下ソースと差し替える。
3. Releaseビルドで実行する。(Debugビルドでは再現しなかったので注意)
省15
191
(14): 2018/09/15(土)20:37 ID:UR1d6CKz(3/5) AAS
ソース:
#include "stdafx.h"
#include <math.h>
using namespace System;

template<typename T> static double calc_norm_and_regulate(int num, T* r, bool regulate){ // <float> for debug.
double norm = 0;
for (int i=0;i<num;i++) norm += (double)r[i] * (double)r[i];
norm = sqrt(norm);
if (regulate) for (int i=0;i<num;i++) r[i] = (T)(r[i]/norm);
return norm;
省17
192
(1): 2018/09/15(土)20:42 ID:UR1d6CKz(4/5) AAS
オプション等(コマンドライン):(全てデフォのままのはずだが一応)
C/C++:
 /GL /D "WIN32" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /FD /EHa /MD /Yu"stdafx.h"
/Fp"Release\test_floating_error4.pch" /Fo"Release\\" /Fd"Release\vc90.pdb"
/W3 /nologo /c /Zi /clr /TP /errorReport:prompt /FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll"
/FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll"
/FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.XML.dll"
リンカ:
/OUT:"MYPATH\test_floating_error4\Release\test_floating_error4.exe"
/INCREMENTAL:NO /NOLOGO /MANIFEST
省6
193: 2018/09/15(土)20:43 ID:UR1d6CKz(5/5) AAS
備考2:
なおこの方法で見える calc_norm_and_regulate 関数の『逆アセンブル』結果は
俺の環境での物とコールアドレス以外は一致していることを確認している。
一応、diff結果は以下。
8c8
< 0000000c cmp dword ptr ds:[00752E14h],0
---
> 0000000c cmp dword ptr ds:[007D2E14h],0
10c10
< 00000015 call 676F58B9
省6
194
(3): 2018/09/16(日)02:47 ID:wIV2HUNW(1/4) AAS
>>190
C++/CLR では、.Net を使っているから、起動方法が違うだけでも、
fpu control word の値や、使うCPU命令がx87 FPUなのか、SSE
なのかが違ってくる可能性があるかもしれない。

fpu control word は、main()関数に入る前の start up codeの中で
初期化される。
195
(1): 2018/09/16(日)03:19 ID:wIV2HUNW(2/4) AAS
>>191
// Release build
// 0.000000, 0x1ff68ddfb62221dd from IDE
// 0.000000, 0x1ff68ddfb62221de from command prompt

それにしても、随分小さな値だね。ちなみに、浮動小数点表示
の場合の有効数字の桁数を上げたら、どのようになる?
1.xxxe-yy
表示にして。
196
(2): 2018/09/16(日)03:40 ID:wIV2HUNW(3/4) AAS
>>191
試しに、ソースの冒頭に
#include <stdio.h>
を追加してから、

Console::Write(String::Format("{0:F6}, 0x{1:x16}\r\n",norm, *(__int64*)&norm));
の部分を、

printf( "%30.30e, 0x%016X\n", norm, *(__int64*)&norm) );

としてみるとどうなる?
197: 2018/09/16(日)03:42 ID:wIV2HUNW(4/4) AAS
>>196
誤: printf( "%30.30e, 0x%016X\n", norm, *(__int64*)&norm) );
正: printf( "%30.30e, 0x%016X\n", norm, *(__int64*)&norm );
198
(5): 2018/09/16(日)07:27 ID:SOVIz+sV(1/15) AAS
> 0x1ff68ddfb62221dd(Debug)
> 0x1ff68ddfb62221de(Release)

VS 2010 VC++ Express でも再現した
199
(1): 2018/09/16(日)07:38 ID:SOVIz+sV(2/15) AAS
↓このループを抜けたあと、すでにReleaseビルドとDebugビルドでは
 normの値に差異が発生してることが確認できた
for (int i=0;i<num;i++) norm += (double)r[i] * (double)r[i];

↓この下に(ループ内に)fprintf文を入れるだけで
 ReleaseビルドとDebugビルドが同じ実行結果になることが確認できた
norm += (double)r[i] * (double)r[i];

とりあえずまずこれだけは分かったから
低学歴知恵遅れが書いたウンココードの問題箇所を限定する
200
(8): 2018/09/16(日)07:51 ID:SOVIz+sV(3/15) AAS
AA省
201
(1): 2018/09/16(日)07:51 ID:SOVIz+sV(4/15) AAS
?-1 デフォルト設定(Release)

↓このコードの逆アセンブルコード
外部リンク:ideone.com

【実行結果】

0x0007F2C44DFFF8F2:1.1053482540585106e-308
202
(3): 2018/09/16(日)07:53 ID:SOVIz+sV(5/15) AAS
AA省
203
(2): 2018/09/16(日)08:02 ID:SOVIz+sV(6/15) AAS
?-2 デフォルト設定(Release)

↓このコードの逆アセンブルコード
外部リンク:ideone.com

【実行結果】

↓実行結果を書き込めないからこっちに書き込んどいた
外部リンク:ideone.com

0x0007F2C44DFFF8F1:1.1053482540585101e-308
204: 2018/09/16(日)08:05 ID:SOVIz+sV(7/15) AAS
?-1 最適化無効 (/Od)(Release)

※ コードは?-1(>>200)と同じ

↓このコードの逆アセンブルコード
外部リンク:ideone.com

【実行結果】

0x0007F2C44DFFF8F1:1.1053482540585101e-308
205: 2018/09/16(日)08:09 ID:SOVIz+sV(8/15) AAS
?-2 最適化無効 (/Od)(Release)

※ コードは?-2(>>202)と同じ

↓このコードの逆アセンブルコード
外部リンク:ideone.com

【実行結果】

※ ?-2(>>203)と同じ
省1
1-
あと 109 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.153s