ボックス内の数値について

返信する


答えを正確に入力してください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: ボックス内の数値について

Double型の端数処理

by DarkSky » 2006年5月17日(水) 04:13

丁度今作っているアプリケーションの中で、似たような関数を使っていたので、稚拙ながらも参考になればと思います。
皆さん文字列の事話し合われてるのに、僕だけ数字の事で恐縮ですが・・・。
Ketaはどの桁まで有効にするかで、Keta+1桁目で切り捨て、切り上げ、四捨五入、五捨六入、JIS丸めを行います。
・・・五捨六入とかJIS丸めとか今まで知らなかったのですが、Wikipedia:端数処理で調べて、面白そうなので付け加えました。勉強になります。

コード: 全て選択


Function RoundDown (dbl As Double, Keta As Long, Mode As Long) As Double
	If dbl = Int(dbl) Then
		RoundDown = dbl
		Exit Function
	End If
	dbl = dbl*10^Keta
	Select Case Mode
		Case 1'切り捨て
			dbl = Int(dbl)
		Case 2'切り上げ
			If dbl - Int(dbl) >= 0.1 Then
				dbl = Int(dbl+1)
			Else
				dbl = Int(dbl)
			End If
		Case 3'四捨五入
			If dbl - Int(dbl) >= 0.5 Then
				dbl = Int(dbl+1)
			Else
				dbl = Int(dbl)
			End If
		Case 4'五捨六入
			If dbl - Int(dbl) >= 0.6 Then
				dbl = Int(dbl+1)
			Else
				dbl = Int(dbl)
			End If
		Case 5'JIS丸め
			If dbl - Int(dbl) > 0.5 Then
				dbl = Int(dbl+1)
			ElseIf dbl - Int(dbl) < 0.5 Then
				dbl = Int(dbl)
			Else
				If Int(dbl) mod 2 Then
					dbl = Int(dbl+1)
				Else
					dbl = Int(dbl)
				End If
			End If
	End Select
	dbl /= 10^Keta
	RoundDown = dbl
End Function
これまたWikipediaより、対応確認表です。長くなってしまいすみません。

コード: 全て選択


#prompt
Dim A As Double
Print "元値","切捨","切上","四五","五六","JIS"
A=8.05
Print A,RoundDown(A, 1, 1),RoundDown(A, 1, 2),RoundDown(A, 1, 3),RoundDown(A, 1, 4),RoundDown(A, 1, 5)
A=8.15
Print A,RoundDown(A, 1, 1),RoundDown(A, 1, 2),RoundDown(A, 1, 3),RoundDown(A, 1, 4),RoundDown(A, 1, 5)
A=8.25
Print A,RoundDown(A, 1, 1),RoundDown(A, 1, 2),RoundDown(A, 1, 3),RoundDown(A, 1, 4),RoundDown(A, 1, 5)
A=8.26
Print A,RoundDown(A, 1, 1),RoundDown(A, 1, 2),RoundDown(A, 1, 3),RoundDown(A, 1, 4),RoundDown(A, 1, 5)
A=8.34
Print A,RoundDown(A, 1, 1),RoundDown(A, 1, 2),RoundDown(A, 1, 3),RoundDown(A, 1, 4),RoundDown(A, 1, 5)
A=8.35
Print A,RoundDown(A, 1, 1),RoundDown(A, 1, 2),RoundDown(A, 1, 3),RoundDown(A, 1, 4),RoundDown(A, 1, 5)
A=8.45
Print A,RoundDown(A, 1, 1),RoundDown(A, 1, 2),RoundDown(A, 1, 3),RoundDown(A, 1, 4),RoundDown(A, 1, 5)
大半は問題なかったのですが、8.26の五捨六入のときがおかしいです。
82.6-Int(82.6)=0.599999999999994となってしまい、切り捨てられるようです。どうすればいいのでしょう?
こんなに遅くまで起きて考え事してると流石に眠くなりますね。

累乗表現

by konisi » 2006年5月16日(火) 23:55

例えば

コード: 全て選択

#prompt
Dim A As Double
A=0.0000000000000005
Print A
と入れたときに、
5.00000000000000e-16
と表示されます。このeで始まる後ろの部分が累乗表現です。

そして。

ここから桁落ちをすると位が滅茶苦茶ずれる結果になります。純粋に。

追記
プログラミングを上達させたい時に、数学の知識が少だけ役立つ事もけっこうあるような気がします。

by 7 » 2006年5月16日(火) 23:47

> それだと、元のDouble型(Single型含)の数値がマイナスの累乗表現になった時に少し困るのでは?
数学弱いので何を弄ればいいんだか分からないんですけど、AcitiveBasicのStr$関数の戻り値の桁数を落としてるだけなので何か問題があるのでしょうね。

by konisi » 2006年5月16日(火) 23:32

>>7s
それだと、元のDouble型(Single型含)の数値がマイナスの累乗表現になった時に少し困るのでは?
僕の作ったStr3$はマイナスの累乗表現に弱いけど、Str2$はそこもしっかり頑張ってくれるよ。
ただしプラスの累乗表現は両方アウト^^;

Re: ボックス内の数値について

by 7 » 2006年5月16日(火) 23:08

> 初めて書き込ませていただきます。
初めまして。

> で、この時に表記される数値を0.1666667とかではなく、エクセルのように
> 小数点以下の桁数を指定して表示する事は可能なのでしょうか?
konisiさんがすでに回答していますけど...。
自分だったらこんな感じにします。

コード: 全て選択

Function GetNumberFormatDecimal(ByVal lpValue As BytePtr,ByVal nDecimals As Long) As BytePtr
Dim length As Long, cnt As Long

	' コンマの位置を取得
	While lpValue[cnt]<>Asc(".")
		cnt++
	Wend

	' コンマまでの文字数と小数点以下の桁数とコンマ自身の 1
	length=cnt+nDecimals+1
	GetNumberFormatDecimal=calloc(length+1)
	memcpy(GetNumberFormatDecimal,lpValue,length)
End Function

' 使い方
Dim str As BytePtr
	str=GetNumberFormatDecimal(Str$(100.123456789),5)

	' 100.12345 と表示されます
	MessageBox(hMainWnd,str,"",MB_OK)

	free(str)

早速ありがとうございます

by bena » 2006年5月16日(火) 22:41

返信ありがとうございます。
試してみます。

by konisi » 2006年5月16日(火) 22:02

Str$関数を自作すれば十分に可能です。

具体的には下のような感じです。

コード: 全て選択


Function Str2$(dbl As Double,sKeta As Long) As String'第二引数は、小数点以下何桁まで表示するかを選びます。あまり数がおおくなると誤差が大きくなります。
	Dim A$ As String
	Dim B$ As String
	Dim I As Long
	A$=Str$(Int(dbl))
	dbl=dbl-Int(dbl)
	If sKeta<=0 then
		Str2$=A$
	Else
		B$="."
		I=1
		Do
			dbl=dbl*10
			B$=B$+Str$(Int(dbl))
			dbl=dbl-Int(dbl)
			If I>=sKeta then Exit Do
			I=I+1
		Loop
		Str2$=A$+B$
	End If
End Function


Function Str3$(dbl As Double,sKeta As Long) As String'第二引数は、小数点以下何桁まで表示するかを選びます。あまり数がおおくなると誤差が大きくなります。
	Dim A$ As String
	Dim I As Long
	A$=Str$(dbl)
	I=InStr(1,A$,".")
	If I=0 then
		Str3$=A$
	Else
		For I=1 To 100
			A$=A$+"0"
		Next I
		Str3$=Mid$(A$,1,InStr(1,A$,".")+sKeta)
	End If
End Function
それぞれ、違う方向からアプローチしてみました。Str2$の方はあまり精度がよくないので、微調整してください。

ボックス内の数値について

by bena » 2006年5月16日(火) 21:36

初めて書き込ませていただきます。
ソフト経験はほとんどありませんので、皆様のご指導・ご鞭撻を賜りたいと存じます。

早速、質問ですが、エディットボックスやコンボボックス内にある数値を書き込む時、

Sub MainWnd_RadioButton1_Click()
Dim a As Byte
Dim b As Single
a = 6
b = 1/a
SetWindowText(GetDlgItem(hMainWnd, EditBox1), Str$(b))
End Sub

のような書き方をしています。
で、この時に表記される数値を0.1666667とかではなく、エクセルのように
小数点以下の桁数を指定して表示する事は可能なのでしょうか?
その方法などありましたらご教示願います。

ページトップ