LoginSignup
3
2

Mind8で倍精度整数の他の変数型からのキャストを実装してみる(5kerD.c)

Last updated at Posted at 2024-04-06

はじめに

諸般の流れから日本語プログラミング言語Mindで固定小数点計算機能を書いてみようかなと思い立ち、Mind開発者の@killyさんのご支援をいただきつつMind8のkernelの修正実行に挑戦中の続きです。

既にこちらの記事で4桁スケーリング固定小数点型の通貨変数を実装してみていますが、ベースとしております倍精度変数(符号付き64bit整数)の初期化の際に、他の変数型からの型変換キャストができるとうれしいなと思い、前回記事で他の整数型変数からの代入による暗黙の型変換の挙動を調査しましたところ、@killyさんよりコメントでAndroid版Mindには倍精度整数へのキャスト単語があることを情報共有いただきましたので、近い感じのものを実装してみることにします。

前提条件

Windows11 Pro 22H2
VSCode(Visual Studo Code) 1.86.1
Microsoft Visual C++ 2008 Express Edition
Mind Version 7.5 for Windows
Mind Version 8.07 for Windows

MindはMind8のバージョンのパスが構成されていることを前提とします。もしも本記事の内容をお試ししたい場合は辞書修正ツールでMind7のライセンスが必要となりますのでご注意ください。

VSCodeの拡張機能

C/C++ for Visual Studio Code 1.18.5 Microsoft
C/C++ Extension Pack 1.3.0 Microsoft

C/C++のデバッガはMind8のCカーネルアプリケーションをデバッグ実行するために使用しています。

お題のソースコード C関数

5kerD.c

独自に追加しているソースファイルです。こちらの記事以降からはMind側で使用する処理単語の他に、それらの単語が呼び出すエラー処理関数も追加しており、c2word用のコメントは記述しなければ辞書の順序は変わらないことをつかんだので、こちらに独自関数や定義を集中します。

符号付32bit整数変数「変数」から符号付64bit整数変数「倍精度変数」への型変換「qキャスト」の他、符号付64bit浮動小数点変数「小数変数」からの型変換「q小数からのキャスト」を実装してみました。

5kerD.c
//~略~
PRIVATE void
    qcast( void )	/* ;WORD qキャスト .N */
{
		LONG		int32;
    	LONG64  	long1;

	/* (int32 → long1) */

	int32 = POP_L_OF_Q;

	long1 = (LONG64)int32;

    push_quad2(long1);
}

PRIVATE void
    qcast_f( void )		/* ;WORD q小数からキャスト */
{
		double		float1;
    	LONG64  	long1;

        /* (float1 → long1) */

	float1 = pop_float();

	long1 = (LONG64)float1;

    push_quad2(long1);
}
//~略~

上記の他にオーバーフローチェック付きの「q一つ加え」、「q二つ加え」、「q一つ引き」、「q二つ引き」を実装しています。

ソースコード全文
5kerD.c

other.c

other.cの内容をすべてダミー定義とします。こちらの記事を参照してください。

kerbody.c

kerbody.cでother.cのインクルードの直前に5kerD.cをインクルードするように追記しています。こちらの記事を参照してください。

Mind7ツールでc_words修正ビルド

こちらの記事をご参照ください。

Mind8ツールでfile修正ビルド

cerror.src

これはMind側のfileライブラリの依存ライブラリのconsoleソースコードです。C側のエラー処理関数から呼ばれる単語になります。こちらの記事をご参照ください。

ここからはMind8のツール、コンパイラを使用します。

シリアル番号チェッカーツール

Mind開発者の@killyさんからMind8ランタイムのシリアル番号チェッカーツールをご提供いただいています。(この記事参照)
今回は開発環境内での変更のため前回のカウントアップ値を保持しますので、ランタイムのシリアル番号チェッカツールは実行しません。

fileライブラリをリビルド

fileライブラリをリビルドして開発環境のlibフォルダにコピーします。

C:\developments\vscode\mind8\kernel>cd ../file  
C:\developments\vscode\mind8\file>mmake obj\file mind
C:\developments\vscode\mind8\file>mcpC -puv obj\file.mco obj\file.sym ..\lib
obj\file.mco -> ..\lib
obj\file.sym -> ..\lib

cerror.srcに追記した記述内容に問題がある場合、コンパイルエラー情報はconsole.infに出力されます。

nmake all

nmake allをターミナルのタスクから実行します。

 *  実行するタスク: nmake all 

ここで追加した関数のC言語的に問題がある場合はエラーで終了することがありますので注意します。

nmake install

nmake allが成功した場合はnmake installも実行しておきます。

 *  実行するタスク: nmake install 

kernel.exeをmrunt010.exeにリネームしてbinフォルダコピー

開発環境のbinフォルダにkernel.exeをリネームしたmrunt010.exeに手動でコピーしておきます。

C:\developments\vscode\mind8>copy bin\kernel.exe bin\mrunt010.exe 
        1 個のファイルをコピーしました。

これ重要です。バージョンチェッカーツールでシリアルNoをあげていれば、コピー忘れは実行時に検知されます。あげていない場合でこのコピーを忘れた場合は古いバージョンの動作となります。

お題のソースコードMindと実行結果

今回リビルドしたfileライブラリを指定してコンパイルします。
こちらの記事をご参照ください。

お題のソースコード(1)

符号付32bit整数変数「変数」の最大値と最小値から符号付64bit整数変数「倍精度変数」への型変換「qキャスト」を実行します。また、参考に前回記事で行った直接代入の結果も併記しました。

varinit2.src
int32は       変数。
int64は 倍精度変数。


メインは
2147483647を int32に 入れ int32を クアド表示2し " "を 表示し int32を 数値表示し  改行し
int32を int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
int32を qキャストし int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
"2147483647"を q文字列初期化し int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
改行し
-2147483648を int32に 入れ int32を クアド表示2し " "を 表示し int32を 数値表示し  改行し
int32を int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
int32を qキャストし int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
"-2147483648"を q文字列初期化し int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
改行し
。

実行結果(1)

PS C:\developments\vscode\mind8\bin> mind ..\sample\varinit2 ..\lib\file

日本語プログラミング言語 Mind Version 8.07 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\pmind\bin\mindex.exe --> ..\sample\varinit2.exe
PS C:\developments\vscode\mind8\bin> ..\sample\varinit2
000000007fffffff 2147483647
000000007fffffff 2147483647
000000007fffffff 2147483647
000000007fffffff 2147483647

0000000080000000 -2147483648
0000000080000000 2147483648
ffffffff80000000 -2147483648
ffffffff80000000 -2147483648

直接代入で符号が反転したマイナス値も無事にキャストして代入できました。:tada:(プラス側ブロック、マイナス側ブロックそれぞれの2行目が直接代入の結果です。)

お題のソースコード(2)

符号付64bit浮動小数点変数「小数変数」の最大値と最小値から符号付64bit整数変数「倍精度変数」への型変換「q小数からキャスト」を実行します。Mindの「小数」の仮数部桁数は15桁、指数部は±308です。この範囲で「倍精度変数」の最大値、最小値に近い値の変換を狙ってみます。

varinit2.src
float64は 小数変数。
int64は 倍精度変数。

メインは
9.223372036854775e18を float64に 入れ float64を クアド表示2し " "を 表示し float64を 14桁で 指数形式で表示し  改行し
float64を q小数からキャストし int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
"9223372036854775807"を q文字列初期化し int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
改行し
-9.223372036854775e18を float64に 入れ float64を クアド表示2し " "を 表示し float64を 13桁で 指数形式で表示し  改行し
float64を q小数からキャストし int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
"-9223372036854775808"を q文字列初期化し int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
。

「指数形式で表示」は符号と小数点、指数記号eを含めて21文字を超えると指数部が文字切れしてましたので、桁数指定を実際の指定値より少ない指定14桁としています。

実行結果(2)

PS C:\developments\vscode\mind8\bin> mind ..\sample\varinit2 ..\lib\file

日本語プログラミング言語 Mind Version 8.07 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\pmind\bin\mindex.exe --> ..\sample\varinit2.exe
PS C:\developments\vscode\mind8\bin> ..\sample\varinit2
ffffffff43dfffff 9.22337203685477e+018
7ffffffffffffc00 9223372036854774784
7fffffffffffffff 9223372036854775807

ffffffffc3dfffff -9.2233720368548e+018
8000000000000400 -9223372036854774784
8000000000000000 -9223372036854775808

仮数部桁数は15桁の範囲内で最大値、最小値を指定した結果は、マイナス値も無事にキャストして代入できました。:tada:

お題のソースコード(3)

指数部の指定によってはオーバーフローが起きえますが、
Mindの「小数変数」の仮数部桁数の正常範囲を超えて「倍精度変数」の最大値、最小値を指数形式でも設定してみます。Mindの「小数変数」の仮数部桁数がオーバーフローしている状態。
Mindの「小数変数」の仮数部桁数の正常範囲内で「倍精度変数」の最大値、最小値を超える値を指数形式でも設定してみます。Mindの「倍精度変数」がオーバーフローしている状態。

varinit2.src
float64は 小数変数。
int64は 倍精度変数。

メインは

9.223372036854775807e18を float64に 入れ float64を クアド表示2し " "を 表示し float64を 16桁で 指数形式で表示し  改行し
float64を q小数からキャストし int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
9.223372036854776e18を float64に 入れ float64を クアド表示2し " "を 表示し float64を 16桁で 指数形式で表示し  改行し
float64を q小数からキャストし int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
改行し
-9.223372036854775808e18を float64に 入れ float64を クアド表示2し " "を 表示し float64を 16桁で 指数形式で表示し  改行し
float64を q小数からキャストし int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
-9.223372036854776e18を float64に 入れ float64を クアド表示2し " "を 表示し float64を 16桁で 指数形式で表示し  改行し
float64を q小数からキャストし int64に 入れ int64を クアド表示2し " "を 表示し int64を $$倍精度表示し  改行し
改行し
。

「指数形式で表示」は符号と小数点、指数記号eを含めて21文字を超えると指数部が文字切れしますが、境界値の動きがわかるように桁数指定を16桁としています。(指数部は文字切れします。)

実行結果(3)

PS C:\developments\vscode\mind8\bin> mind ..\sample\varinit2 ..\lib\file

日本語プログラミング言語 Mind Version 8.07 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\pmind\bin\mindex.exe --> ..\sample\varinit2.exe
PS C:\developments\vscode\mind8\bin> ..\sample\varinit2
0000000043e00000 9.2233720368547758e+0
8000000000000000 -9223372036854775808
0000000043e00000 9.2233720368547758e+0
8000000000000000 -9223372036854775808

00000000c3e00000 -9.2233720368547758e+
8000000000000000 -9223372036854775808
00000000c3e00000 -9.2233720368547758e+
8000000000000000 -9223372036854775808

まず、Mindの「小数変数」のプラス値の仮数部オーバーフローは9.223372036854775807e18と指定しても16桁目で丸められて9.223372036854776e18と同じ状態になるようでした。いずれも「倍精度変数」の最大値を超えていて、「倍精度変数」へのキャストはマイナスの最大値に変換されました。

マイナス値の仮数部オーバーフローは、Mindの「小数変数」の仮数桁数としてはオーバーフローしていない-9.223372036854776e18を指定しても、「指数形式で表示」の16桁指定の表示が-9.2233720368547758e+となっているためちょっとわかりにくいですが、仮数桁数としてはオーバーフローしている-9.223372036854775808e18とは16進数表示も同じなので、オーバーフローしている方はオーバーフローしていない方に丸められていると推察されます。
-9.223372036854776e18は「倍精度変数」の最小値を超えていて、「倍精度変数」へのキャストはマイナスの最大値に変換されました。
-9.223372036854775808e18は「倍精度変数」の最小値と同じですが、Mindの「小数変数」としてはオーバーフローして「倍精度変数」の最小値を超えた状態に丸められて「倍精度変数」へのキャストはオーバーフローしたと推定されます。

おわりに

浮動小数点の扱いは仮数指定の限界あたりの扱いがめんどうですね。固定小数点型へのキャストにあった方がよいかなと思い実装してみました。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2