
cのrand()関数を使用せずに、
16bitの整数演算で、乱数を生成したいのですが、
何か良い方法はありませんでしょうか?
以下のように作ってみたのですが、時と場合によっては、
繰り返しになるみたいです。
なお、8bitのPICマイコンを使用しております。
宜しくお願い致します。
****longを2バイトとする。***
#define _ULONG unsgined long
_ULONG g_ulSeed = 31;
_ULONG rand2()
{
_ULONG ulTemp;
g_ulSeed = ( 2045 * g_ulSeed ) % 32768;
g_ulSeed = g_ulSeed % 0xfff0;
// 上位8bitと下位8bitの入れ替え
ulTemp = ( g_ulSeed & 0xff ) << 8;
g_ulSeed = ulTemp | (g_ulSeed >> 8 );
return g_ulSeed;
}
No.1ベストアンサー
- 回答日時:
★アドバイス
・簡単な数式を使って擬似乱数を作ります。
下にその一例を載せます。
数式を可変するといろいろと乱数が変わります。
サンプル:
unsigned int MyRand( unsigned long init )
{
static unsigned long seed;
if ( init != 0 ){
seed ^= init;
}
seed *= 128945376;
seed += 35;
return (unsigned int)((seed >> 12) & 0xFFFF);
}
その他:
・MyRand() 関数の第一引数の初期値を与えると最初の乱数が別の数になります。
特に指定しない場合は 0 を指定して下さい。
・適当な数 128945376 を掛けて 35 を足して long 型の 32 ビットから適当な 16 ビットを
戻り値としています。この辺は自由にカスタマイズして下さい。
・以上。
この回答への補足
すみません。質問者です。
お礼の欄に記述できないようですので、
ここに記します。
乱数の計算はやっているみたいなのですが、
どうもseed *= 128945376;の計算が重いらしく、
不安定な動作になってしまいます。
せっかく、教えていただいたのに、
すみません。
ありがとうございます。
処理能力が低いマイコンを使用しておりますので、
seed *= 128945376;
の部分がうまくいくかどうか分かりませんが、
早速、実行してみます。
後で、結果をご報告します。
No.3
- 回答日時:
M系列乱数
・t1,t2は基となる値(seed)の指定された位置のビットの状態。下記の例では2と5を使いました。
・この2つのエクスクルーシブORをとり、seedを1ビットシフトしてできたすき間(下記の例では最下位ビット)にいれる。
このくり返しです。
ただしseedの初期値は0以外を使う必要があります。(0で始めると1以外の値が出力されません)
論理演算だけなので速い(軽い)はずです。
-------------- ここから ----------------------------------
#include <stdio.h>
unsigned short NewRandom(unsigned short r)
{
unsigned short t1,t2;
t1 = (r&(1<<2))?1:0;
t2 = (r&(1<<5))?1:0;
r <<= 1;
r |= (t1^t2);
return r;
}
int main(void)
{
unsigned short r=0xabcd;
while ( 1 )
{
r = NewRandom(r);
printf("%04x\n",r);
}
return 0;
}
非常に、シンプルですね。
M系列って、聞いた事はありますが、
難しそうで、理解していません。
確か、乱数周期が、他の方法に比べて
長いのですよね。
ただ、試しに、vc++で動かしてみましたが、
なぜか途中で計算されなくなってしまいました。
PICマイコンでは動きました。
原因を考えてみます。
ありがとうございました。
No.2
- 回答日時:
★アドバイス
>8bitのPICマイコンを使用しております。
↑
8Bit なので 32Bit の long 型は重くなるのですね。
では 16Bit 版を紹介します。
サンプル:
unsigned int MyRand( unsigned int init )
{
static unsigned int seed;
if ( init != 0 ){
seed ^= init;
}
seed *= 52341;
seed += 37;
return (seed ^ 0x1234);
}
↑
こんどのはどうでしょうか。
試して見て下さい。
※乗算そのものが重い処理になるならまた別タイプを載せます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) Visual Studio Code 関数の使い方について 3 2023/05/31 13:15
- Visual Basic(VBA) VBAでArrayListを使う為の「mscorlib.tlb」の参照設定について 3 2022/03/23 19:45
- Excel(エクセル) Excel 2019 32-bit版を64-bit版にするには? 8 2023/07/28 14:20
- TOEFL・TOEIC・英語検定 bitとlittleは両方ともに同じ 1 2022/08/10 13:03
- その他(AV機器・カメラ) オーディオインターフェイスの24bitなど量子化bit数はどこで設定できるのでしょうか? 1 2022/06/26 07:58
- 英語 英文和訳についての質問です。 2 2023/06/23 06:38
- Excel(エクセル) 幾何学模様のセル内貼り付け 1 2023/07/11 00:45
- スピーカー・コンポ・ステレオ DAC[について・・・ 1 2022/08/29 11:44
- C言語・C++・C# C言語 3 2022/10/04 15:07
- Excel(エクセル) エクセルで同じ数字同士を自動で線で結ぶVBAを教えてください 6 2022/04/26 23:13
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C++で表を作成したいのです ...
-
Visual C++ フレームを中央に表...
-
画像の拡大・縮小
-
whileとifを使い偶数を出すには
-
2次関数プログラムを描写する...
-
再起呼び出しの回数をカウント...
-
intとlongは同じ?
-
MFCでネガポジ変換
-
C言語の関数について。
-
再帰処理をループ処理に変換
-
低次元なコーディング方法について
-
C++ bmp 透過処理
-
C言語プログラミング 漸化式に...
-
カードシャッフルのブログラム...
-
コマンドプロンプトのウィンド...
-
2の補数を計算するプログラム
-
OpenCVによる4値化について
-
argvのNULLチェック
-
C++デバックエラーについて詳し...
-
opencvとmbedのシリアル通信で...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
2の補数を計算するプログラム
-
intとlongは同じ?
-
条件が多い場合
-
再起呼び出しの回数をカウント...
-
argvのNULLチェック
-
C言語でDOS画面のプログラム(...
-
カードシャッフルのブログラム...
-
c++ TCHARで文字化け
-
複数の共有メモリの作成
-
C++ Debug Errorについて教えて
-
C++ bmp 透過処理
-
関数とビット列
-
OpenCVによる4値化について
-
コマンドプロンプトのウィンド...
-
ヌメロンのプログラム
-
for 分についてです
-
DXライブラリとC言語 fwrite関...
-
16bitで乱数を生成する方法
-
プログラミングに関して
-
C++で表を作成したいのです ...
おすすめ情報