浮動小数点演算の微調整

4月に職場に来た人の歓迎会をやってほしいという話があって、

いろいろ考えるもなかなか思うようにいかないものである。

でもとりあえず手配はできたからいいか。


浮動小数点数は難しいなと思うことがあった。

マイコンで測定した値を一定の演算を行うと、例えば-100~100の値に変換される。

この値が指定された値を出たらフラグを立てるという処理がある。

ここで-100, 100ピッタリを指定した場合、フラグは立ってはいけないと思った。

ところがこの処理、浮動小数点演算で行わざるを得ず、変換後の値が-100~100をわずかにはみ出すことが判明。

この結果、-100, 100ピッタリを指定した場合もフラグが立つことがあると。


整数演算でやればこういう問題は避けられた可能性はあるが……

指定された値が –100, 100 ピッタリの場合に動作する処理を加えようかとか、

比較する前に整数化してしまうか、とかいろいろ考えたのだが、

浮動小数点演算の量が増えるのはあまり好ましいことではないか……

なんてことを考えた結果、変換時のパラメータを微調整することで解決した。

例えばパラメータに 1666.666 となっていたのを 1666.668 にするとか。

最終的な演算結果では浮動小数点の仮数部の1digitの差とか、そんなところを突き詰める微調整だった。

結果として従来のアルゴリズムはほぼ変えずに問題を解決できた。


こういう解決方法ってどうですかね? とチームリーダーに相談にいくと、

微調整により他の部分の演算結果が若干変わるけど影響ないかと。

測定結果のばらつきの方が大きいだろうと断言できる話である。

しかし、これだけ細かい微調整だと、移植などで影響も受けそうだが。

特に移植を想定しているわけではないが気になるところである。


過去に浮動小数点演算であれこれやったことが一度あったが、

そのときは測定値の端がとんでもない数字に吹っ飛ぶ仕組みだった。

なのでこういう問題は考えることもなかった。

そもそも –100, 100のような端の値を指定したときにフラグが立たないなんて約束はどこにもなかったのだが、

社内ではこういう考えが一般的なので、これも大丈夫だっけ? とテストすると案の定ダメという。

バーコードの格納方式いろいろ

以前、CODE128とQRコードの符号化方式を紹介したことがある。

CODE128という方式らしい, 数字だらけのQRコードにした意味

CODE128は1次元コードとしては高密度な方式で、コンビニ用の払込書などで使われている。

103種類のシンボルを持っており、数字2桁を1シンボルで表せる。

ASCIIコードの0x20~0x7Fと0x00~0x5Fを切り替えてASCII文字を全て表現することができ、

切替で128種類の文字を表現できることがCODE128の由来である。

QRコードは点1つが1bitの情報を持つが、数字モード、英数字モード、バイナリモード、漢字モードの格納方法がある。

バイナリモードは単純に8bit単位、数字モードは3桁を10bit、

英数字モードは数字・大文字アルファベットからなる45種類を2文字で11bitとする。

漢字モードはShift_JIS前提なので今どきどうか思うが1字13bitである。


昨日紹介したスタック型バーコードのPDF417だが、

これは928種類のシンボルを1単位としている。必ずバーから始まりスペースで終わるので、

シンボルの切れ目のところには全行ともスペースとバーが揃う。

900番以降のシンボルはモード切替などの制御用のシンボルなので、

基本的には900個のシンボルを効果的に使って表現することとなる。

その方式にはテキスト圧縮モード・バイト圧縮モード・数字圧縮モードがあるそう。

もっともシンプルなのがテキスト圧縮モードで2文字を1シンボルに格納する。

ただ、30文字ではアルファベット全部は入るが数字は入らない。

大文字・小文字・数字他・記号の4ページに分けて相互に切り替えるキャラクタ含めて30字としているそう。


数字圧縮モードは最大44桁を最大15個のシンボルに変換する。

90015=2.06×1044という計算なのだが、符号化前に頭に1を付加するので、

1の次に9が44個続く数字、すなわち 1.99…×1044 まで符号化できる必要があると。

ちょっと無駄な気はするが、17桁の数字は1.99…×1017<9006 より6個のシンボルで表現できる。

バイト圧縮モードは6バイトを5個のシンボルに変換する。

この2つは相当複雑だから用途が限られてそうだなと思う。

バイト圧縮モードは1文字だけ切り替える制御コードもあるようなので、

基本アルファベットで表せない文字の符号化に使われてるのかも。


いろいろ格納できるコードはいろいろ工夫があるということですね。

ただ、PDF417は英数字の格納に特化している印象はある。

CODE128は英数字1文字が数字2桁相当、QRコードは英数字2文字より数字3桁の方が小さい。

なので数字ばかり格納するとかなりお得である。

ただPDF417は英数字30個で数字44桁だから、そこまでお得感はない。

もっともこれらのコードそれぞれ英数字の表現方法は異なるので単純比較はできないが。

ただ、QRコードの英数字モードは45種類に含まれない文字は一切表現できないので、

URLの格納などはバイナリモードによらざるを得ないとかでけっこう不利ですよね。

そもそもがコンパクトだからそれでも便利に使われてるけど、

能力をフルに発揮しやすいのは断然数字モードだなと思う。

CODE128はそれに比べれば柔軟性は高いと思う。

1次元バーコードなんで、どう頑張っても格納できるサイズには限りがあるが。

AVIFという画像フォーマット

以前、このサーバーの隠しページにWebPで画像を集めている話を書いた。

SafariとInternet ExplorerがWebP非対応であることもあって、WebPへ一本化というのはまだ現実的ではなく、

(自分のサーバーに画像を置きたかった)

これが2019年の話だが、2020年にSafariがWebPに対応したそう。

そしてそれを追うようにAVIFにも対応したということも書かれていた。

Chromeが2020年、Firefoxが2021年、Safariが2022年、Edgeはちょっと遅れて2024年に対応したという。

WebPでSafariが大きく遅れたことと比べるとだいぶ足並みは揃っている。


AVIFというのは画像のフォーマットとは思えない名前だが、

AV1 image formatの略で、AV1はAOMedia Video 1の略である。

そう、AVIFは画像のフォーマットだと言いながら、VはVideoから来ている。

なんのこっちゃという感もあるが、そもそもWebPもそうだった。

WebPはGoogleが開発している動画コーデックVP8を静止画に適用して作られた形式である。

動画コーデックAV1の静止画形式がAVIFということである。


GoogleはVP8を発展させたVP9を作り、さらに発展させたVP10を作ろうと考えていたが、

多数の会社が参加するAOMediaというコンソーシアムに合流して、

ここにVP10として開発していた技術を投入、AV1コーデックに結実している。

VP8に対してWebPがあるように、AV1にはAVIFがあるということである。

概念的には似ているがWebPはRIFF(AVIもRIFFコンテナの一種)である一方、

AVIFはHEIFというコンテナを使っている点も異なる。


面倒な話なのだが、HEIFというのはMPEG規格の1つで、

HEVC(H.265)でエンコードされた動画・静止画の格納を目的としている。

その場合の拡張子としては hevc(動画), heic(静止画)とするのが通例である。

MPEG4に対するMP4コンテナみたいな話ですね。

これをAV1でも使うことにしたようだが、静止画はそれでよいのだが、

動画の方ではMP4コンテナの方が使われてるっぽい。


WebPの後継という点では間違えなくAVIFなのだが、

次世代画像フォーマットという点ではHEICというのも存在する。

形式や発想は同じで使っているコーデックがHEVC(H.265)というだけの違い。

ただ、HEICはSafari以外は対応していない。

iPhoneで写真を撮るとHEICで保存される設定になっていることがあり、

後で変換に苦労するという話もあるが、ほぼiOS専用に近い状況である。

静止画ではAVIFの方が圧倒的である。


WebPと比べると、より小さなファイルサイズでも画質を保ちやすい傾向にあるそう。

WebPの変換に使っているXnViewでもちゃんと対応していた。

XnViewはマイナーな形式もカバーするソフトとして有名だから当たり前だけど、

GIMPも読み書きできるし、Windows 11のフォトでも開けるみたい。

ともあれXnViewで変換をしてみたが……えらい遅いのだが。

AVIFというかAV1の問題らしいが、エンコードが遅い傾向にあったという。

現在は改良された方式もありHEVC(H.265)にもひけを取らないものもあるようだが。


WebPと比較したときのAVIFの欠点としてエンコードの遅さが書かれている。

XnViewでは変換速度の設定があり、最速の10にするとだいぶ速くなった。

それでも1000枚変換してWebPは12秒、AVIFは40秒だから、相当遅いことは事実である。

今回の用途では全く問題ない所要時間ではあるが、

オンデマンドで画像を変換・生成するという用途では気になるかもしれない。

そういう話をするとJPEGのような古典的な形式の方がいいのかもしれないが。


WebPと比べるとAVIFはスピード導入という印象はあるが、

それはAOMediaという大手企業がこぞって参加したプラットフォームの成果物だからかも。

AV1の目的はロイヤリティフリーで利用できるコーデックとすること。

動画のコーデックは様々な特許を利用しており、実施には使用料の支払が必要な場合がある。

デジタル放送を受信する機器にはロイヤリティーも含まれている。

これ自体は昔からあった話だが、HEVC(H.265)は多くの特許権者が絡み、複雑化している。

これを問題と思った企業が技術を持ちよって作ったのがAV1である。

インターネットでの利用に重きを置いており、まずは静止画が先行した形である。


ただ、これに前後してWebPの導入も進んだので、AVIFでなければならないわけではないが。

WebPが時代遅れになったとは解釈しない方がよさそうだ。

レジスタを書き換えて回路切断

認証機関が製品の立会試験でこれをみたいというリクエストを送ってきて、

その中に○○の信号を切断するとという項目があった。

うーん、切断ですか。


でも、回路中に直列の素子がないから、簡単にはできないんだよねと。

で、気づいたのだがマイコンのGPIOで出力しているのだが、

GPIOで出力設定のピンを入力設定に切り替えれば同じ効果があるのでは? と。

なぜならば入力設定にしたピンは外部からハイインピーダンスに見えて、

出力レジスタの値は無視されることになるからである。


最終的にはこの設定を切り替えるコードを組み込んで、

特定の操作を行った時に呼び出されるようにした。

すると、回路切断時に起こるであろう挙動が発生した。

というわけでとりあえずよさそうである。


ただ、この方法もちょっと困った話があった。

この信号を切断するとという信号を切断すると、

マイコンは一旦外部からリセットされるが、まもなく復帰する。

ただ、復帰後に通常通り初期化すると、信号の切断が戻ってしまう。

そこでこのケースについては、リセット後も保持されるレジスタにマークして、

起動時にこのマークを発見したら、再度同様の設定をするようにした。

こうすると切断が継続しているのと同じになる。

この場合の挙動がまたくせ者ではあったのだが、想定通りの挙動となり一安心。


あとは検査官がこれでよいと認めるかですけど。

そもそも回路の切断ってなんだよという話ですけど。

ただ、信号をHi, Loに固定するのも、それはそれで難しく、

結局一番簡単なのはGPIOのモード切替だったのかなと。

これも最初はICEでブレークして書き換えることを考えたが、

それだと思った動きにならないのでコードを組み込んだ事情もある。

いろいろ難しいんですよね。

ATOK Passportが倍額になったので

だいぶ前からATOK Passportを契約して使っているが、

今年2月からプレミアムに一本化され、従来月額330円で使っていたのが660円と倍額になった。


そもそもプレミアムは以前から存在したのだが、

大きな違いがAndroid・iOS版でProfessional版が使えることである。

そもそもATOK Passportを有料で契約しているのはスマートフォン・タブレット用という側面が大きい。

当然PCでも使ってはいるし、これはこれで恩恵があるのだが、

正直Microsoft IMEもそんなに悪くないとは思う。(職場ではこれだし)

でも、Androidでは日本語変換への不満が大きかったわけですね。

で、ATOKを使っていて、そこそこ賢いがPC版に比べると劣ると思っていた。

これがProfessional版が登場し、PC版同等になったという説明である。


このProfessional版を使用するための契約がATOK Passportプレミアムだった。

ただ、倍額ってのは高いなと踏ん切りが付かなかったのである。

おそらくそういう人は多かったんじゃないかと思う。

で、今年から一本化して、強制的にプレミアムに切り替えさせたわけである。

強引な話だし、当然これを機にやめた人もいるとは思うが、

それならProfessional版に切り替えるかと考えた僕のような人もいるだろう。

というわけでスマートフォン・タブレットにProfessional版をインストールしていた。


正直、PCだけで使っている人はメリットを感じにくいかもしれない。

ATOKというのもどんな人がつかっているかという話はあるのだが、

昔は一太郎に付属していたが、現在一太郎に付属するのはATOK Passportの使用権1年分である。

ゆえに一太郎のおまけで使うというものでもなくなっている。

それだけにATOKクラウドの各種機能に自信を持っているということである。

ATOK Syncという複数デバイスでの同期機能はあるが1台なら関係ない。

クラウド機能でもっともわかりやすいのはクラウド推測変換か?


ATOK Passport プレミアムの場合、対象となる語句数が増えるらしい。

ただ、ベーシック版でも存在する機能だけに差がわかりにくい。

明確な差としては辞書を呼び出して使える機能が追加されたことがある。

変換させるときに、その語句の国語辞典など参照できると。

なぜか和英辞典が参照できたりもするが、どういう使い方を想定しているのか。


今後、ATOK Syncの機能強化などクラウド機能の強化が計画されており、

これのATOK Passportプレミアムへの一本化の背景にあるようだ。

ATOK Passportを使い倒している人なら価値は感じられるだろうが、

必ずしもそういう利用者ばかりではないだろうからね。

一太郎のおまけで使っていた人はもう振り落とされているし、

月額330円で使っていた人も今振り落としたわけである。

ATOKは使う人をかなり選ぶものになっていると言えそうだ。

Android版という観点では予兆はあったのだが、PC版では寝耳に水だっただろうし。

ここがやめ時と思った人が多いのも頷ける話である。

コードカバレッジを測る

評価計画を立てる作業を進めているが、その一環でコードカバレッジの測定をしていた。

評価を行うとどれぐらいコードが網羅できるかという話だから、

コードカバレッジの測定は計画時にしておく方がいいわけですよね。

他の工程との兼ね合いである程度時間が取れるからという側面もあるが。


コードカバレッジ測定用のツールはあるのだが、それでも容易とは言えないんだよな。

評価に使用する予定の設定情報を入れて動かしたり、

評価に使用する補助ツールで評価予定の項目を流したりして、そのときのコードカバレッジを見た。

思ったより網羅度は高かったが、やはりいろいろ通らないところはある。


ただ、ここは通らんだろうなというコードも多かった。

APIが成功コードを返さなかった場合はエラー処理に入るというコードを書いたが、

このAPIが失敗することはおおよそ考えられんだろうというのもある。

そういうのは「通過禁止」とセットすると計算から除外する機能があった。

「通過禁止」というのは良い言葉ですね。

コード上存在するが、このコードを通るようなことはあってはいけないと。

ある関数はそんなパスが10個以上存在していて驚いてしまった。


その上で通っていないパスをいろいろ検討していく。

このパスは○○のエラー処理を検証するから通るとか机上検討で埋めていく。

このパターンの評価は抜けていたなと気づけば評価項目に書く。

そのパターンの設定を加えたり、補助ツールの評価項目一覧に加えたり。

すると、それをきっかけにして見つかるバグってのもあるんですね。

絶対に通るはずだと思っていたパスが通らないので、他の部分の記述ミスを発見したり。

ある種の設定を50個以上並べると動作がおかしくなるバグがあって、

50個以上並べた場合にある操作を行った時だけ通るコードに記述ミスがあったと。

まさにデバッグ時のコードカバレッジが足りてなかったわけですね。

現実問題としてこんな個数並ぶことがあるのかはよくわからないけど。

しかし評価項目に入ってないのは盲点だったので書き加えておいた。


あと、抜けが目立ったのがUARTのフレーミングエラーですね。

普通にやっていてもフレーミングエラーなんて起きないからな。

評価項目に加えないといけないが、実現方法は難しいなと。

本来より大幅に遅いボーレートで通信をすれば容易に発生させることはできるが、

その場合に所定の動作になっているかというのは案外難しい。

誤った通信データを送るというのは全体的に難しいですね。

そういうのは発生し得ないと「通過禁止」とするのはさすがにダメだろう。


ただ、思ったより最初から高いカバレッジが出たのはよかったですね。

全然カバレッジがないと、どうやって埋めるか骨が折れただろうから。

精査してみると「通過禁止」や机上検討で明らかなものが多く、

この条件が抜けだねとみてすぐにわかるものが多かった。

まぁこの辺はコツがわかっているからというのもあるんだろうが。

IT管理者向けマニュアルが届く

職場でノートPCのUSBポートが壊れて、レンタル業者から代替機が届いて、

データを動かして、あれこれ新規インストールしてとやっていた。

もうこのツールはいらないかなというのは省略しつつ、

新しいバージョンのツールがリリースされているなという気づきとか、

アップデートするとなんかうまく動かないというのもあったり……


そんな中で全社的に提供されているツールをインストールしようとすると、

なんかエラーが出てうまくインストール出来ない。

手順を再確認したが、やはりうまくいかないので問い合わせた。

すると、この資料をみながらやってねというのが送られてきたのだが……

どう見てもIT管理者向けのマニュアルなんだが?


トラブルシュートの記載に今回の事象が載っているのかと思ったがそうではない。

というわけで頭から順番に見てみると、インストール内容を定義するXMLファイルの記載が間違えていた。

サンプル通りに記載を直すと正しくインストール出来た。

というわけで一件落着……でいいのか?


というわけでこう直したらうまく行ったけど、インストールキットは直さないの?

と連絡すると、別の担当者からインストールキットが間違えていたから直すという回答。

どうも最近、配布を始めたばかりで間違えていることに気づいてなかったらしい。

といっても、元の設定でちゃんと検証していたのかなど、謎は多い。


なぜ僕にIT管理者向けのマニュアルが送られてきたのか?

正直なところよくわからないところもあるのだが、

どうも外注業者がいて、分担しながらITインフラのマネージメントをしていると。

で、この問い合わせフォームへの回答は社内のIT担当者も外注業者もできるようになっている。

ここには何らか分担があるのだろうと思う。

で、その外注業者が問い合わせの背景など理解せずに管理者向けのマニュアルを送ってしまったのだろうと。

本当は社内のIT管理者に送って、お前らでどうにかしろという話だったのかもしれない。

そういうアドバイザーがいるのはなるほどねとは思うんですけど。


というわけで解せない話だった。

こういうインストールキットのミスは時たま発生していて、それに巻き込まれた話は時々聞く。

複雑な設定を排して簡単に共通的な環境をインストール出来るようにという工夫だが、

ちょっとしたミスで標準環境と乖離したり、そもそも動かなかったり……

まぁだいたい初期には何か起きてるんだろうなと思いますね。

AWAでプレイリストを公開する

僕はAWAという音楽の定額配信サービスを使っている。

AWAを知ったのはLinksMateのカウントフリーに入っていたことから。

LinksMateはCygamesの子会社が経営しており、ゲームのカウントフリーオプションで知られる。

主にはCygemesを含むサイバーエージェント関連の会社が関与しているゲームだが、そうでないものもある。

で、実はゲームだけじゃないんですよ。ABEMAやdアニメストアといった動画配信もある。

そして音楽配信という観点ではAWAがあると。サイバーエージェントの子会社が経営している。


といってもLinksMateを使ってるわけではないんですけどね。

当初はGoogle Play決済で安いということで使い始めたわけだが、

現在はクレジットカード決済と差が付いたので、Google Play決済ではない。

定額配信サービスの中ではちょっとマイナーな方かもしれないが、

基本的なところはあまり変わらないので、これはこれでよいのではないか。


そんなAWAで「THE IDOLM@STER M@STERS OF IDOL WORLD 2025」でセットリストのプレイリストを作っていた。

こういうの公式で出てくるのもあるんだけど……

でもAWAで作ってるのはあまり見ないか。(バンドリはAWAでは作ってない)

自分用に作るわけだが、せっかくなら他の人も使えるように公開しようとするのだが、

AWAのプレイリスト公開には大きな制約があるのである。

それは必ず8曲でなければならないということである。


公式アカウントで作るプレイリストはその限りではないんだけどね。

というわけでまず、自分用に全部並べたプレイリストを作る。

公式で公開されているセットリストを見ながら検索して投入していく。

Day1は57曲中52曲、Day2は60曲中53曲が入った。

8曲以上あるプレイリストを公開すると頭8曲分だけ共有されるので、

以降を8曲ずつ別のプレイリストにコピーしていく。

すると7つのプレイリストになる。最後は適当な曲で埋めておく。

これでとりあえず全曲を共有することが出来た。


これをどう使うかは各自にお任せということにはなるのだが、

オススメの使い方は自分のプレイリストにコピーすることである。

AWAでは公開されているプレイリストを自分のプレイリストにそのまま追加することができる。

すなわち自分でMoIW2025 Day1とかプレイリストを作って、

1番目から7番目まで順番に「プレイリストに追加」で加えていく。

すると最初から最後まで1本になったプレイリストが完成する。

最後に長さ調整のために埋めた曲は消しておけば完璧である。


ところで実際の楽曲とプレイリストに追加できた曲数には乖離があるが、

これはいずれも765PRO ALLSTARSの楽曲である。

シンデレラガールズはゲームに入っている曲は少なくともショートサイズで登録されているので、

これはなんやかんやいっても全部見つかっている。

765はアニメで使われた一部の楽曲を除いてさっぱり登録されていない。

以前、こんな話を書いたのだが、実際には放置状態である。

なお、日本コロムビアが発売元なのはアイドルマスターの無印もそうだが、

こちらは圧倒的に古い楽曲が多いため、定額配信を出し渋る理由は薄いと思う。

累積で聞かれることが定額配信のメリットとなると書いたことがあてはまる。

(日本コロムビアはCDを売りたい)

シンデレラガールズは来年春頃に定額配信をフルサイズ化する話が出ている。

これはデレステ更新停止に伴う対応の一環のようである。

シンデレラガールズの更新停止

シンデレラガールズに新規に触れる人のためにデレステと定額配信を使いたいと。

その理屈でいえば765なんてもうとうに終わってるやろとなるんですけどね。

現実はほとんどないという状態である。ダウンロード販売では大概買えるだろうけど、調べてはない。

何比較してもfalseになるNaN

評価計画を立てているときに、浮動小数点演算の結果が無限大になったときの処理も確認しないとな。

というところでIEEE754形式の浮動小数点数の資料を見たら、

NaNというのもあることを思いだし、これがけっこうなくせ者だった。


特殊な浮動小数点数として +0, –0, +∞, –∞とNaNがある。

+0と-0はどちらも0なのだが、符号ビットの概念が存在する。

通常は+0を使うのだが、計算によっては-0が生じることがある。

とはいえ大概の場合、意識する必要はない。

+∞, -∞はゼロ除算で生じることが比較的多い。

1.0/0.0=+∞, -1.0/0.0=-∞ といった具合である。

数学的には正しいとは言えないけど、概念的にはわかりますよね。


NaNは “Not a Number”の略で、漢字で書けば「非数」ってことになる。

なんのこっちゃという話だが、何らか未定義の値が出てくるとこうなる。

ゼロ除算でも 0.0/0.0 の場合は±∞ではなく NaN となる。

∞が絡む演算では 0.0×(±∞) や ∞-∞ は NaNとなる。

また、虚数が生じる演算 sqrt(-1.0) のような計算も NaN となるそう。

NaNが絡む演算も通常はNaN になるので 0.0/0.0+1.0 も NaN+1.0=NaNとなる。


浮動小数点数をスケーリング・整数化して表示する処理がある。

ここに +∞, –∞とNaN をそれぞれぶち込んでみた。

+∞, -∞は上限・下限に貼り付くような動作で、これはこれでよい。

しかしNaNは0になってしまった。一体なぜか。

float fval = roundf(forg * fscale);
if(fval < (float)SHRT_MIN){
     shortval = (short)SHRT_MIN;  //(1)
}else if(fval > (float)SHRT_MAX){
     shortval = (short)SHRT_MAX;  //(2)
}else{
     shortval = (short)fval;      //(3)
}

まず、forg×fscaleを四捨五入で整数化した値をfvalとして求める。

この値が -32768(SHRT_MIN)~32767(SHRT_MAX) であればそのままshortvalに代入する。

-32768未満であれば-32768、32767超であれば 32767 に丸める。

この処理で forg=-∞, fscaleが適当な正の数だと fval=-∞ となる。

-∞<SHRT_MIN なので(1)に分岐し、-32768 となり下限に貼り付く。

forg=+∞もfval=+∞となれば +∞>SHRT_MAX なので(2)に分岐し 32767 に貼り付く。


問題は forg=NaNで、fval=NaNとなった場合である。

実はNaNと他の数の比較はすべてfalseとなるルールがあるそうで、

NaN<0 も NaN>0 も NaN==NaN すらもfalseとなるのである。

すなわち、上記の(1)にも(2)にも該当せず、

あたかも -32768~32767 の範囲にあるかのように(3)に入る。

こうなったNaNをどのように整数変換するかは処理系依存だが、ARMでは0となるようだ。


ところでここまでの処理で例外とか発生しないの? と気になった人もいるかもしれない。

ARMではゼロ除算など不正な演算をしても例外にならないのが通常である。

レジスタ設定により例外を発生させることもできるみたいだけど。

ARMでは整数演算で0除算をすると0になるというルールを持っており、

100/0 のような演算をうっかりやってしまうと 0になるんですね。

x86はゼロ除算で例外が発生するのだが、必ずしもそうではないと。


何を比較してもfalseになるのが功を奏したものもあって、

a<bの場合に動作する処理を if(a<b){ … }else{ … } と書くと、aかbがNaNだとelse側に入ることになる。

数値比較してfalse側にフォールバック的な動作があればよいのだが、

逆に範囲外の処理をtrue側に書くと、ひっかからないということが起こる。

とりあえずNaNを何か範囲外相当の処理に落とし込みたいわけである。

というわけで考えたのはこういう書き方である。

if(!(fval >= (float)SHRT_MIN)){

「SHRT_MIN未満」という書き方を、あえて「SHRT_MIN以上でなければ」としている。

NaN以外の数に対する動作は何ら変わらない。

NaN >= SHRT_MIN は falseになるので、これを反転するとtrue になる。

これにより従来の書き方では分岐しなかった(1)の処理に入り、

fval=NaNは便宜上 -32768 に変換されることになる。

いかにも異常な数字であることが気づける可能性が高まる。


実際のところ +∞, –∞, NaN なんて発生させちゃいけないんですけどね。

ただ、設定次第で発生する可能性は否定できないので、

その場合でもなんらか説明ができる動作にしておくべきという話ですね。

比較順序によってはあまり問題にならないんですけどね。

ただ、意識して作らないとなかなかうまくいかないだろうなとは思った。

TeraTermでバイナリデータを受信する

マイコンの処理時間の測定をして、処理能力の見積もりをしていた。

処理量が多いと勝手に遅くなっていくという構造で、

一体どのぐらいあると遅くなるのかというのが見えてなかった。

おそらくほとんどの場合は最速ペースで動けそうなのだが、

遅くなるケースもちゃんと評価しないといけないのでね。


で、取得したデータを吐き出す方法をどうするかという話があって、

UARTで‘0’を送ると、測定データをバイナリで吐き出すようにした。

バイナリなのは文字列への変換が面倒だったからなのだが、

果たしてバイナリデータを保存するのは容易に出来るのか?

と、TeraTermのログ機能を見ると「バイナリ」という出力モードがあった。

バイナリでログを有効化して、’0’をタイプして、ログ終了して、

ログファイルをバイナリエディタで開くと所望のデータが得られた。

これでいいのか。


バイナリデータを送るのは面倒なのに、受信するのは簡単なんだな。

と思ったが、よく考えればファイルをドラッグアンドドロップすれば、

そのデータをバイナリで送信するということはできるんだった。

(この送信というのはYMODEMなど使わずに、単純にデータ列として送るということ)

だからあらかじめバイナリデータのファイルをあれこれ用意しておけば、

決まったバイナリデータをTeraTermで送るのは容易だったらしい。


後処理など考えればPythonなのかVBAなのか、送受信してデータ処理するプログラムを作るべきかも知れないが、

とりあえずデータを取ってくるという点ではこれで楽に出来た。

おかげでサクッと取って進めることが出来た。

ICEでメモリダンプするというのもあるけど、それだと実態に合わないのでは? という懸念もあったので。