【Rustで作る電卓】組み込み関数をDefsに流し込む #25

前回は、しばらくの間実装していた三角関数についてまとめました。
三角関数などの自作関数は単体で呼び出し検証はできていますが、計算機からは読み込めません。そこで今回は、組み込みおよびあらかじめ定義しておく関数を電卓から呼び出せるように、ハッシュ化と構文解析で利用できるようにしていきます。

1. Definitions(関数定義)に追加

作成した累乗・対数関数(power.rs)、三角関数(math/trigonometry.rs)の電卓用関数は pubで定義してあるので外部から参照可能です。ただし、これをそれぞれ呼び出すのは面倒+管理が大変なので、Definitionsで一元管理できるようにしました。

// Defsの自作関数と同じように読み込めるようにする。(builtinは組み込み関数用の構造体)
    pub fn register_builtins(&mut self) {
        // ライブラリクレート (tucalc) の math モジュールを参照して関数ポインタを取得
        use tucalc::math::{basic, trigonometry};

        // --- 1引数関数 (Unary) ---
        // 高精度化された三角関数群
        self.builtins.insert("sin".to_string(), BuiltinFunc::Unary(trigonometry::sin));
        self.builtins.insert("cos".to_string(), BuiltinFunc::Unary(trigonometry::cos));
        self.builtins.insert("tan".to_string(), BuiltinFunc::Unary(trigonometry::tan));
        
        // 基本的な数学関数
        self.builtins.insert("abs".to_string(), BuiltinFunc::Unary(basic::abs));
        self.builtins.insert("ceil".to_string(), BuiltinFunc::Unary(basic::ceil));
        self.builtins.insert("floor".to_string(), BuiltinFunc::Unary(basic::floor));
    }

今後関数が増えても、それぞれ個別で作り、ここに呼び出すときの関数名と関数自体のポインタを配置すれば、関数電卓から呼び出せるようになります。(呼び出し名のかぶりについては最後に呼び出したもので上書きされるようになっています)

2. TUIから呼び出してみる

TUIから呼び出してみます。

TUIからtan(1)を呼び出し計算できた様子

試しに tan(1) を計算できるか試してみました。
結果は 1.557408となり、うまく呼び出せているようです。

3. 公開を見据えてちょこっと修正

今作っているTUI電卓(tucalc)は、最終的には、すべてのrustユーザが ”cargo install tucalc”でインストールできるようにすることを目標にしているので、絶対参照になっていた(defsなどを)linuxの作法に従って、相対参照に修正しました。

// mainの初期化のところ  
  
    // ホームディレクトリを取得してパスを構築
    let home = std::env::var("HOME").unwrap_or_else(|_| ".".to_string());
    let config_dir = format!("{}/.config/tucalc/defs", home);

    // フォルダが存在しなければ作成しておく(初回起動時の親切設計)
    let _ = std::fs::create_dir_all(&config_dir);

    // 構築した絶対パスを渡す
    let res = run_app(&mut terminal, &config_dir);

4. 次なる関数:指数関数と双曲線関数

少し短いですが、今回はここまで、作成した個別の関数を電卓から呼び出せるようにする仕組みを作りました。対数と三角関数の実装はできましたが、初等関数には指数関数や双曲線関数などがまだまだ残っています。

予告:ちょっとした「箸休め」のつもりが……?

次回からは少し趣向を変えて、指数関数 \(e^x\) の実装に進んでみます。ネイピア数eは、面白い性質をたくさん持っているため\(e^x\) の実装でも工夫ができたらいいなと考えています。

「周期性がないから三角関数より簡単だろう」と思うかもしれません。確かに範囲還元の複雑さは軽減されますが、指数関数には「爆発的な増大」と「微小な値の保持」という新しい課題が待っています。

そして、この \(e^x\) の実装こそが、その先に控える「双曲線関数(\(\sinh, \cosh, \tanh\))」を攻略するための唯一にして最強の武器となります。

  • 三角関数は「円」の性質
  • 双曲線関数は「指数」の性質

次回 : (記事は現在利用できません: ID 7741)