« オフカメラシューコード改造 | トップページ | ビニール結束線 »

2021年1月30日 (土)

8bit乱数関数 random8()

2021年1月28日:Arduinoの乱数関数「random」に違和感
に関係して、
2021年1月22日:出窓に「跳ねるLED」 では
Adafruit_NeoPixel-master」のライブラリを用いましたが、
LEDテープの制御、もう一つの有名どころが
FastLED-master」です。

これを使ったサンプルやライブラリのソースを見ていると
こんな乱数関数を見つけました。

普通のrand()は16bitの正の値(0~32767)を返しますが、
桁数8bitでエエやん用に作られてます。
「C++」ですんで、引数で処理を区分。
こんな結果になります。

   random8()    == random from 0..255
   random8( n)   == random from 0..(N-1)
   random8( n, m) == random from N..(M-1)

ここでも最大値は「N-1」あるいは「M-1」に。

random8()だと「0~255」が出てくるのに、
random8(255)とすると得られるのが「0~254」と
いう値になってしまいます。

そして、この場合「(255 + 1)」とは記せません。
入力引数も8bitですんで256はアウト。
random8(n)で最大値255は永遠に出てきません。
random8(0, 255)
でも255は出せません。
random8() では255が出るのに・・・。


random8(n)とrandom8(n, m)のソース、こんな処理です。

uint8_t random8(uint8_t lim)
{
  uint8_t r = random8();
  r = (r*lim) >> 8;
  return r;
}

uint8_t random8(uint8_t min, uint8_t lim)
{
  uint8_t delta = lim - min;
  uint8_t r = random8(delta) + min;
  return r;
}


「剰余」を使わず、「(random8() * lim)」で符号無しの
16bit値を得て、それを1/256 (8回右シフトというか上位桁
だけ使う)して符号無し8bitの乱数を得ています。

「剰余を使った乱数」と「1/256での処理」、違いはいかが
でしょうか。
統計に強い人に確かめていただきたい。

 

|

« オフカメラシューコード改造 | トップページ | ビニール結束線 »

Arduino」カテゴリの記事

コメント

続き・・・
2021年2月 3日:FastLED-masterにある8bit乱数関数
http://igarage.cocolog-nifty.com/blog/2021/02/post-480bdf.html

投稿: 居酒屋ガレージ店主(JH3DBO) | 2021年2月 5日 (金) 08時39分

コメントを書く



(ウェブ上には掲載しません)




« オフカメラシューコード改造 | トップページ | ビニール結束線 »