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

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

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

Re[5]: VBでLong型以上の整数値の取り扱い


(過去ログ 79 を表示中)

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

■46970 / inTopicNo.1)  VBでLong型以上の整数値の取り扱い
  
□投稿者/ tonton (6回)-(2010/02/15(Mon) 15:07:21)

分類:[VB6 以前] 

VB6を使用していますが、
Long型の変数lA、lB、lC とあって
lA=lB*lC の計算式でオーバーフローしました。

lB・・・2000
lC・・・2000000
で計算上4000000000となり範囲を超えてしまったようです。
今までFDの計算で使用していたのがDVDでも使用する事になりこの結果です。
VBではどのようにしたらよいのでしょうか?整数で小数点以下はありません。マイナスもありません。

引用返信 編集キー/
■46973 / inTopicNo.2)  Re[1]: VBでLong型以上の整数値の取り扱い
□投稿者/ ダッチ (5回)-(2010/02/15(Mon) 15:48:40)
tonton さん、こんにちはダッチです。

Currency型とかどうですか。
引用返信 編集キー/
■46974 / inTopicNo.3)  Re[1]: VBでLong型以上の整数値の取り扱い
□投稿者/ はつね (1192回)-(2010/02/15(Mon) 15:50:24)
No46970 (tonton さん) に返信
> VB6を使用していますが、
> Long型の変数lA、lB、lC とあって
> lA=lB*lC の計算式でオーバーフローしました。

Currency型はどうでしょうか?

引用返信 編集キー/
■46977 / inTopicNo.4)  Re[2]: VBでLong型以上の整数値の取り扱い
□投稿者/ tonton (8回)-(2010/02/15(Mon) 15:58:04)
はつねさん、ダッチさんありがとうございます。

もうちょっと調べますがDoubleであれご指摘のCurrencyであれ
うまくいくと思いやってみたのですがうまくいきません。
実はVB6でもXP上で実施するとうまくいき、Win2000やVistaはダメです。
調べきれていないので一概にOS?とも言えませんし、コードの別のところが問題の可能性もあります。

ちなみにテストコードはこんな感じです。
Dim lngA, lngB, lngC As Long

lngB = 2048
lngC = 2294385
lngA = lngB * lngD * lngC

引用返信 編集キー/
■46979 / inTopicNo.5)  Re[3]: VBでLong型以上の整数値の取り扱い
□投稿者/ Blue (31回)-(2010/02/15(Mon) 16:01:55)
>Dim lngA, lngB, lngC As Long
これだと、Long型になるのはlngCだけだけど大丈夫ですか?
引用返信 編集キー/
■46982 / inTopicNo.6)  Re[4]: VBでLong型以上の整数値の取り扱い
□投稿者/ tonton (9回)-(2010/02/15(Mon) 16:38:39)
No46979 (Blue さん) に返信
> >Dim lngA, lngB, lngC As Long
> これだと、Long型になるのはlngCだけだけど大丈夫ですか?

あぁすいません・・・VB初心者なもので・・・しかもlngDなんか宣言してないし・・・
Dim lngA As Long
Dim lngB As Long
Dim lngC As Long
にしました。

それでやっぱりXPでもオーバーフローしました・・・

ちなみに
Dim lngA As Currency

lngA = CCur(lngB) * CCur(lngC)

に変えたらうまくいきました・・・CCur()は片方だけでもいいようですが・・・
ちなみに
lngA = CCur(lngB * lngC)
はダメでした。
なにかヒントになりますか?



引用返信 編集キー/
■46985 / inTopicNo.7)  Re[5]: VBでLong型以上の整数値の取り扱い
□投稿者/ なちゃ (392回)-(2010/02/15(Mon) 17:05:52)
計算した瞬間にオーバーフローするのですから、
計算する前にCCurしてやらないとだめですよ、ってことです。

ちなみにDoubleでは解決になりません。
エラーはでなくなっても、正しい答えにはなりませんので。

引用返信 編集キー/
■46987 / inTopicNo.8)  Re[6]: VBでLong型以上の整数値の取り扱い
□投稿者/ みきぬ (784回)-(2010/02/15(Mon) 17:09:51)
> ちなみにDoubleでは解決になりません。

解決にならないかどうかは用途次第ではないかな、と。
引用返信 編集キー/
■46993 / inTopicNo.9)  Re[5]: VBでLong型以上の整数値の取り扱い
□投稿者/ はつね (1194回)-(2010/02/15(Mon) 20:28:02)
No46982 (tonton さん) に返信
> あぁすいません・・・VB初心者なもので・・・しかもlngDなんか宣言してないし・・・
> Dim lngA As Long
> Dim lngB As Long
> Dim lngC As Long
> にしました。

元の変数自体をCurrency型にするって意味でCurrency型はどうでしょうか?と書いたつもりでした。


> ちなみに
> Dim lngA As Currency
>
> lngA = CCur(lngB) * CCur(lngC)

Long型で宣言しておいてCCur使うなら上記のように関連する変数すべてにCCurを個別に
行って演算するのが安全です。

引用返信 編集キー/
■46995 / inTopicNo.10)  Re[6]: VBでLong型以上の整数値の取り扱い
□投稿者/ tonton (10回)-(2010/02/15(Mon) 21:15:05)
なるほどですね・・・変数にセットする前に型は効いているんですね(当然か・・・)
より安全というのであればCCurはすべての式に入れます。

ありがとうございました。
解決済み
引用返信 編集キー/
■47000 / inTopicNo.11)  Re[1]: VBでLong型以上の整数値の取り扱い
□投稿者/ よねKEN (439回)-(2010/02/15(Mon) 22:28:50)
2010/02/15(Mon) 22:29:18 編集(投稿者)

正攻法で解決済みですので余談です。

> 今までFDの計算で使用していたのがDVDでも使用する事になりこの結果です。

空き容量の計算か何かかなと想像しているのですが、精度がざっくりでよければ、
バイト単位ではなくキロバイト単位で扱うようにして桁数をかせぐというアプローチもありかもしれませんね。
#用途によるとは思いますが、DVDなら容量目一杯使えなくてもあまり困らない場合も多いと思うので。

もちろん厳密な要求がある場合はダメですけどね。

解決済み
引用返信 編集キー/
■47020 / inTopicNo.12)  Re[2]: VBでLong型以上の整数値の取り扱い
□投稿者/ tonton (11回)-(2010/02/16(Tue) 12:28:15)
そうですね。。。確かに手としてはアリですね。
空き容量の計算ではあるのですが、暫定的な対応らしいので
書き込めるサイズ(件数)はFDと今回DVD-RAMを使用するのですが
同じ件数となるので贅沢ですがFDの書込み件数MAXになると
DVD-RAMでも2枚目を要求します(笑)
引用返信 編集キー/
■47023 / inTopicNo.13)  Re[3]: VBでLong型以上の整数値の取り扱い
□投稿者/ tonton (12回)-(2010/02/16(Tue) 14:06:22)
すいません・・・助けてください・・・(涙)

lngA = (CCur(lngB) * CCur(lngC)) \ 512

のような箇所があってオーバーフローしました・・・なんででしょう???
引用返信 編集キー/
■47027 / inTopicNo.14)  Re[4]: VBでLong型以上の整数値の取り扱い
□投稿者/ みきぬ (788回)-(2010/02/16(Tue) 14:25:37)
VB6 のことはよくわからないので勘ですが、\ 演算子が Currency 型で使えなくて、Long あたりで頑張ろうとしてオーバーフローしているんじゃないですかね?

工夫すればなんとかなるかな。

bq を lngB / 512 の商、br を lngB / 512 の余り
cq を lngC / 512 の商、cr を lngC / 512 の余り
として、

lngA = (CCur(lngB) * CCur(lngC)) \ 512
   = ((512 * bq + br) * (512 * cq + cr)) \ 512
   = (512 * 512 * bq * cq + 512 * (br + cr) + br * cr) \ 512
   = 512 * CCur(bq) * CCur(cq) + br + cr + (br * cr) \ 512

# どーでもいいですが、lngA As Currency ってすっげー違和感があるから変数名も直したほうが
引用返信 編集キー/
■47029 / inTopicNo.15)  Re[4]: VBでLong型以上の整数値の取り扱い
□投稿者/ tonton (13回)-(2010/02/16(Tue) 14:34:40)
自力で調べたところ・・・

lngA = (CCur(lngB) * CCur(lngC)) \ 512

だとどうも格納前に各値がLongに変換される?ような事が
http://msdn.microsoft.com/ja-jp/library/25bswc76(VS.80).aspx
に書いてあって、

Dim lngA As Currency
の場合には

lngA = (CCur(lngB) * CCur(lngC)) \ 512

lngA = (CCur(lngB) * CCur(lngC)) / 512
と同じ気がするのですが・・・
か、
lngA = Fix((CCur(lngB) * CCur(lngC)) \ 512)
とした方がいいのでしょうか?



引用返信 編集キー/
■47031 / inTopicNo.16)  Re[5]: VBでLong型以上の整数値の取り扱い
□投稿者/ みきぬ (789回)-(2010/02/16(Tue) 14:59:50)
No47029 (tonton さん) に返信
> lngA = Fix((CCur(lngB) * CCur(lngC)) \ 512)
> とした方がいいのでしょうか?
>
lngA = Fix((CCur(lngB) * CCur(lngC)) / 512)

ですよね?
おそらくは (何か) \ 512 を計算しようとするときに、(何か) を Long にしようとしてオーバーフローしているので、(何か) \ 512 の結果に Fix 関数を適用しようとしても意味がないです。

で、/ 演算子に直した場合ですが、
・/ 演算子が Currency 型も扱える(* がそうだから大丈夫だと思うけど)
・負数はあり得ない、もしくは考慮済み
・Fix 関数が Currency 型も扱える。または、lngB * lngC / 512 の商が Long の範囲を超えないことが確実
の条件を満たしていれば大丈夫じゃないかなと思います。
引用返信 編集キー/
■47032 / inTopicNo.17)  Re[5]: VBでLong型以上の整数値の取り扱い
□投稿者/ tonton (14回)-(2010/02/16(Tue) 16:30:12)
負数はないですね。メディアの容量計算なので。
Currency 型が扱えるのかは試した結果がOKだから扱えると信じます・・・
追加で質問した計算式は結局lngA はLong型にしました。
Currency 型でも通りましたが諸事情により。
Fixは入れないとCurrency 型ではダメなようです。
最終的には

Dim lngA As Long

lngA = Fix((CCur(lngB) * CCur(lngC)) \ 512)
で落ち着きました。

※Dim lngA As Currency は実際のソースではやってないです。
 サンプルコードも慌てて書いたので紛らわしくてスイマセン・・・



解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -