HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2013
1024
甘酒氏HSPで論理シフトがしたい5解決


甘酒氏

リンク

2013/10/24(Thu) 16:12:17|NO.57777

HSPで疑似乱数を作ろうと思いまして、真っ先に思い浮かんだのがxorshiftなのですが、

XorShiftは符号無し整数を使う事になっていて、ビットシフトも論理シフトを使う事になっているらしいです。
算術シフトですると、乱数の最上位ビットが必ず(?)0になってしまうようです。

HSPで論理シフトをすることは可能でしょうか・・?



この記事に返信する


asdfjkl;

リンク

2013/10/24(Thu) 17:29:21|NO.57780

論理シフトをする関数を作る事も可能ですが
xorshiftの処理が遅くなるのでおすすめしません。

論理シフトと算術シフトは、
シフトする対象の符号ビットが0であれば挙動はまったく同じだったと思います。

なので、符号ビットを常に0にすれば算術シフトも論理シフトも変わりません。
その代わり1ビットを無駄にするので、扱える数字の最大値は1/2になります。

具体的には、符号ビットは最上位ビットなので
シフトする前に0x7FFFFFFFでマスクするだけです

a = -1 //符号ビットは無視するので表示する場合0x7FFFFFFFでマスク //実際には常に符号ビットを0にするので、普段このマスクは必要ない mes strf("%X",a&0x7FFFFFFF) //符号ビットを0にするために&でマスク a &= 0x7FFFFFFF //このタイミングのaが普段使われる //mes strf("%X\n",a) //シフト a >> 1 mes strf("%X",a)



check

リンク

2013/10/24(Thu) 17:42:40|NO.57781

XorShiftならアルゴリズムも簡単だし、
C言語でDLLを作って呼び出したほうが速度的にも速くていいかもしれない。

一番は標準のrndだろうけれど。



甘酒氏

リンク

2013/10/25(Fri) 10:48:50|NO.57791

!なるほど、0x7FFFFFFFでマスク・・その手がありましたか!!
無事解決しました!ありがとうございます!



RRR

リンク

2013/10/25(Fri) 13:49:11|NO.57802

>>シフトする前に0x7FFFFFFFでマスクするだけです
xorshiftで使うためと決まっているなら論理シフトだって特定の値でマスクするだけなので計算量は変わらないのでは。
たとえば a>>19 なら a>>19&0x1fff という風にすればいいです。
ついでに汎用な右論理シフトをマクロで書けばこうですね。
#define global ctype rshift(%1,%2) ((%1)>>(%2)&((2<<(31-(%2)))-1))

さらについでに以下のページの一番下のxorshiftのサンプルをHSPで書けばこうですね。 http://hexadrive.sblo.jp/article/63660775.html
seed@xorshift= 123456789, 362436069, 521288629, 88675123
#module xorshift
#deffunc init_xor128 int _s
	s=_s
	repeat 4
		s=1812433253*(s^(s>>30&3))+cnt
		seed(cnt)=s
	loop
	return
#defcfunc  xor128
	dup a,seed
	t=(a(0)^(a(0)<<11))
	a(0)=a(1): a(1)=a(2): a(2)=a(3)
	a(3)=(a(3)^(a(3)>>19&0x1fff))^(t^(t>>8&0xffffff)) 
	return a(3)
#global



asdfjkl;

リンク

2013/10/25(Fri) 14:32:48|NO.57804

RRRさんの回答が1bit無駄にしませんし計算速度も
マクロを使わない場合は同じなので、一番いいと思います。

僕自身とても勉強になりました、ご指摘ありがとうございます。



ONION software Copyright 1997-2023(c) All rights reserved.