メニエスの名のもとに

プログラミング関係を中心としたぐだぐだブログ

重大なバグ

TinyMT と XSadd についての重大なバグが報告されました。

xsadd_float, xsadd_double, tinymt32_generate_float, tinymt64_generate_double 関数は[0, 1)区間の浮動小数点数、つまり0以上1未満の数を返すはずですが、バグにより1.0を返すことがありました。
修正済のバージョンは
https://github.com/MersenneTwister-Lab/TinyMT
https://github.com/MersenneTwister-Lab/XSadd
からダウンロードして下さい。

浮動小数点数への変換バグ

TinyMTとXSaddの前に開発したSFMTとMTGPでは、浮動小数点数への変換はIEEE 754形式のビットパターンを作って、それを浮動小数点数として解釈し直すという方式でした。この方式は、SIMDGPUでは高速なのですが、通常のCPUでは一度メモリに書いてから読み直すので遅くなります。それでも、一度にまとめて疑似乱数を作成する場合には、もともとそのためのメモリアクセスがあるので遅くならないのですが、呼び出しの度に疑似乱数を生成する方式では遅くなります。
TinyMTやXSaddの開発動機は、メモリの小さな疑似乱数生成器を作ることにあったので、SIMDも一度にたくさんの疑似乱数を生成するという方法も使わないと決定しました。そこで、32-bit の符合なし整数を232で割って[0, 1)区間の疑似乱数を作ったわけです。これはdoubleなら正しいのですが、floatの場合は間違いになります。floatの仮数部の精度は24ビットしかないので、0xffffffffに1.0f/(232)を掛けると1.0fになってしまうのです。
オリジナルのMersenne Twister では、和田維作さんによるgenrand_res53がしっかりとした処理をしているのに、退化させてしまいました。ああ、恥ずかしい。これは完全に私のミスで松本眞先生のせいではありません。松本眞先生はこの開発の頃から、あるいはその前から大変忙しくて、細かいところは見ていないのでした。私が疑似乱数の開発に慣れてきたので、そんなに見なくても大丈夫だろうと思ってくれたのだと思います。
64ビットの符合なし整数からdoubleに変換する場合も同様の問題があります。解決法は32ビットからfloatを作る場合は8ビット右シフトしてから1/(224)で割るというものです。maskしてから割ってもいいのですが、上位ビットの方が乱数性が高いので上位の24ビットを使います。

上付き文字がでないのは困る

はてなブログでは、<sup></sup>で上付き文字が出ないのが困る。それどころか下付文字になる。