2020-12-14
Facebookグループ「IchigoJam-FAN」で開催中の「IchigoJamで欲しい機能アンケート」、USBキーボード対応、HDMI出力に次いで3位が小数対応。

一般的に小数の計算は遅くなります。特にIchigoJamで使っているような小さなCPUでは小数計算用の回路もないので、遅くなってしまいます。MSX BASICでは基本変数は小数として扱われ、DEFINTA-Zで整数として宣言することで高速化するテクニックがありました。また小数計算を導入する場合、どのような文法にするかは悩ましい問題。

小数を使った計算をしたくなることは確かにあります。16bitのIchigoJam変数の範囲に収まるようにどう計算式を組み立てるか考えたいときなどに便利です。そこで頼るは、ネットの力。IchigoJamの無線LAN拡張ボード、MixJuiceに対応した小数計算サービスを作りました。(src on GitHub)

?"MJ GETS app.sabae.cc/svrcalc/?2.1+2.2 4.300000000000001

このように結果が返ってきます!四則演算のみに対応しています。

IchigoJam web の I/O → MixJuice オプションでも動きます。

作り方と、微妙な誤差についての解説。

借りているサーバー app.sabae.cc に、式が届いたら結果をテキストで返すプログラムをDeno/JavaScriptで書いて動かしっぱなしにしています。

import { createApp } from "https://servestjs.org/@v1.1.7/mod.ts"; import { calc } from "./calc1.js"; const main = (q) => { return calc(q) + "\r\n"; }; const app = createApp(); app.get(/\/*/, async (req) => { const q = req.url.lastIndexOf("?"); if (q < 0) { return; } const s = req.url.substring(q + 1); const body = main(s); const headers = new Headers({ "Content-Type" : "text/plain", "Access-Control-Allow-Origin": "*", }); await req.respond({ status: 200, headers, body }); }); app.listen({ port: 3001 });

コアになる計算する部分 calc1.js はこういう感じ

const calc = (s) => { const n = s.match(/(\d+(\.\d+)?)([\*|\+|\-|\/])(\d+(\.\d+)?)/); if (!n) { return "err"; } const a = parseFloat(n[1]); const b = parseFloat(n[4]); const op = n[3]; switch (op) { case "*": return a * b; case "+": return a + b; case "-": return a - b; case "/": return a/ b; } return "err"; }; // console.log(calc("0.1+0.2")); export { calc };

正規表現を使って受け取った文字列から数2つと演算子を取り出し、計算結果を返しています。 JavaScriptでの数は、IEEE 754 の倍精度 64ビットバイナリ形式、2進法による浮動小数なので0.1を正確に記録できません。使いたい精度に合わせて適宜丸めましょう。

なぜ、denocalcのように、evalを使わないのでしょう?
ヒントはサイバーセキュリティ。アクセス制限をしていないサービス、悪意を持った人に好き勝手されないよう気をつけましょう。
→ 中高生向けサイバーセキュリティ教育プログラム「CyberSakura

SSL化や、いろんなサービスへと接続するフロントとして、nginxというwebサーバーを使っています。

$ vi /etc/nginx/nginx.conf server { ... location /svrcalc/ { proxy_pass http://localhost:3001/; } $ nginx -s reload $ git clone https://github.com/taisukef/servercalc.git $ cd servecalc $ nohup deno run -A server.js &

試しに「https://app.sabae.cc/svrcalc/?2+2」などとアクセスし、4が返ってきたら成功!

サーバーが自在に使えると楽しいですよ!
時給1円のサーバーくんをプログラミングで自在に操ろう! クラウド入門 ConoHa API編

Tweet
クリエイティブ・コモンズ・ライセンス
本ブログの記事や写真は「Creative Commons — CC BY 4.0」の下に提供します。記事内で紹介するプログラムや作品は、それぞれに記載されたライセンスを参照ください。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / 「一日一創」画像 / RSS