型変換の関数作成

typecast関数の紹介... 1

浮動小数点の説明... 1

浮動小数点を非負の1バイトに型変換する関数の作成... 1

非負の1バイトを浮動小数点に型変換する関数の作成... 1

typecast関数の作成... 1

 

typecast関数の紹介

ある書式のバイナリデータの読み書きしたいと思います。

自分は、ファイルを全部をuint8で読み込んで、MATLABtypecast関数で試行錯誤することが多いです。

type castというのは型キャスト、型変換と訳されます。型というのは整数や浮動小数点などの型です。

typecast関数というのは

>> typecast(3.14,'uint8')

ans =

   31  133  235   81  184   30    9   64

>> typecast(single(3.14),'uint8')

ans =

  195  245   72   64

>> typecast(uint8([31,133,235,81,184,30,9,64]),'double')

ans =

    3.1400

>> typecast(uint8([165,245,72,64]),'single')

ans =

    3.1400

といった感じで、nバイトの型があるとした場合、その型の各バイトの中身を表示したり、また任意のバイトから型を指定することで、数字に変換できたりします。

 

浮動小数点の説明

4バイト浮動小数点は

で表します。ここでsは正負の符号signfは仮数部fractioneは指数部exponentです。

3.144バイト浮動小数点float (single)では

01000000 01001000 11110101 11000011

となります。2進数表示です。

0は正負の符号(1bit)で、正です。

1000000 0は指数部(8bit)1*2^7+0*2^6+0*2^5+0*2^4+0*2^3+0*2^2+0*2^1+0*2^0=128です。規則でこの値から127を引いた値が指数となりますので、128-127=1となり、指数部は2^1=2となります。

1001000 11110101 11000011は仮数部(23bit)で0のところを無視すると2^(-1)+2^(-4)+2^(-8)+2^(-9)+2^(-10)+2^(-11)+2^(-13)+2^(-15)+2^(-16)+2^(-21)+2^(-23)=0.5700となりますが、規則で1を足した値、1.57となります。

1.57×2=3.14で符号は正です。

これをバイト単位でみていきますと

01000000=64, 01001000=72, 11110101=245, 11000011=195となります。

typecastの答えと順番が逆になっていますが、little endian(小さい桁から記載する)だからです。

64bitの場合、メモリ上のアドレスは例えば以下のようになります。

0x00000028B5AFFB48 = 0xC3 = 195

0x00000028B5AFFB49 = 0xF5 = 245

0x00000028B5AFFB4A = 0x48 = 72

0x00000028B5AFFB4B = 0x40 = 64

0x16進数を意味します。尚、NeuromagFIFFファイルはbig endian(大きい桁から記載する)になっています。

順序が逆になりますので上記の場合は

0x00000028B5AFFB48 = 0x40 = 64

0x00000028B5AFFB49 = 0x48 = 72

0x00000028B5AFFB4A = 0xF5 = 245

0x00000028B5AFFB4B = 0xC3 = 195

等となります。

同様にdoubleを見ていきます。8バイトの浮動小数点は

で表されます。

3.14doubleでは

01000000 00001001 00011110 10111000 01010001 11101011 10000101 00011111

となります。符号部1bit、指数部11bit、仮数部52bitです。指数部の引き算はfloat127と異なり、1023となります。

バイト単位でみていきますと

01000000=64, 00001001=9, 00011110=30, 10111000=184, 01010001=81, 11101011=235, 10000101=133, 00011111=31となります。

little endianですので、小さい桁から並べると31,133,235,81,184,30,9,64となります。

64bitの場合、メモリ上のアドレスは例えば以下のようになります。

0x000000953A3BF7C8 = 0x1F = 31

0x000000953A3BF7C9 = 0x85 = 133

0x000000953A3BF7CA = 0xEB = 235

0x000000953A3BF7CB = 0x51 = 81

0x000000953A3BF7CC = 0xB8 = 184

0x000000953A3BF7CD = 0x1E = 30

0x000000953A3BF7CE = 0x09 = 9

0x000000953A3BF7CF = 0x40 = 64

符号、指数部はfloat(single)と同じです。

1001 00011110 10111000 011 (float)

1001 00011110 10111000 01010001 11101011 10000101 00011111 (double)

仮数部は23bit目以降が異なっていますが、誤差の範囲内でほぼ0.57です。

結局1.57×2=3.14となります。

 

浮動小数点を非負の1バイトに型変換する関数の作成

C言語のポインタ機能を使って以下のようなファイルを作成し、test04.cという名前で保存しました。

#include "api_scilab.h"

#include <localization.h>//_(**)のときに必要?

#include <Scierror.h>//Scierrorを使うとき必要

#include <malloc.h>

 

int double2byte(char *fname, void* pvApiCtx)

{  

    //エラー表示用

        SciErr sciErr;

 

        //1変数

        int m = 0, n = 0;

        int *piAddressVar = NULL;

        double *matrixOfDouble = NULL;

 

        //1引数のcheck

        //address取得

        sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVar);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

        //doubleで虚数でない

        if (!isDoubleType(pvApiCtx, piAddressVar) || isVarComplex(pvApiCtx, piAddressVar))

        {

                 Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), fname, 1);

                 return 0;

        }

        //行列の取得

        sciErr = getMatrixOfDouble(pvApiCtx, piAddressVar, &m, &n, &matrixOfDouble);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        int i = 0, j = 0;

        int row = 8, col = m*n;

        unsigned char *p;

 

        //1戻り値

        unsigned char* newMatrix = NULL;

        newMatrix = (unsigned char*)malloc(sizeof(unsigned char*)*row*col);

 

        //引数と戻り値の数のcheck

        //string=double2hex(double)

        CheckInputArgument(pvApiCtx, 1, 1);//引数は1

        CheckOutputArgument(pvApiCtx, 1, 1);//戻り値は1

 

        for (i = 0; i < col; i++)

        {

                 p = (unsigned char*)&matrixOfDouble[i];

                 newMatrix[j] = *p;

                 newMatrix[j+col] = *(p + 1);

                 newMatrix[j+col*2] = *(p + 2);

                 newMatrix[j+col*3] = *(p + 3);

                 newMatrix[j+col*4] = *(p + 4);

                 newMatrix[j+col*5] = *(p + 5);

                 newMatrix[j+col*6] = *(p + 6);

                 newMatrix[j+col*7] = *(p + 7);

                 j++;

        }

 

        //1戻り値用行列のポインタ作成

        sciErr = createMatrixOfUnsignedInteger8(pvApiCtx, nbInputArgument(pvApiCtx) + 1, col,row, newMatrix);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        //1戻り値をScilabに渡す

        AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;

 

        ReturnArguments(pvApiCtx);

 

        return 0;

}

 

int single2byte(char *fname, void* pvApiCtx)

{

        //エラー表示用

        SciErr sciErr;

 

        //1変数

        int m = 0, n = 0;

        int *piAddressVar = NULL;

        double *matrixOfDouble = NULL;

 

        //1引数のcheck

        //address取得

        sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVar);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

        //doubleで虚数でない Scilabsingleは使えないので・・・

        if (!isDoubleType(pvApiCtx, piAddressVar) || isVarComplex(pvApiCtx, piAddressVar))

        {

                 Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), fname, 1);

                return 0;

        }

        //行列の取得

        sciErr = getMatrixOfDouble(pvApiCtx, piAddressVar, &m, &n, &matrixOfDouble);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        int i = 0, j = 0;

        int row = 4, col = m*n;

        unsigned char *p;

 

        //1戻り値

        unsigned char* newMatrix = NULL;

        float x;

 

        newMatrix = (unsigned char*)malloc(sizeof(unsigned char*)*row*col);

 

        //引数と戻り値の数のcheck

        //string=double2hex(double)

        CheckInputArgument(pvApiCtx, 1, 1);//引数は1

        CheckOutputArgument(pvApiCtx, 1, 1);//戻り値は1

 

        for (i = 0; i < col; i++)

        {

                 x = (float)matrixOfDouble[i];

                 p = (unsigned char*)&x;

                 newMatrix[j] = *p;

                 newMatrix[j + col] = *(p + 1);

                 newMatrix[j + col * 2] = *(p + 2);

                 newMatrix[j + col * 3] = *(p + 3);

                 j++;

        }

 

        //1戻り値用行列のポインタ作成

        sciErr = createMatrixOfUnsignedInteger8(pvApiCtx, nbInputArgument(pvApiCtx) + 1, col, row, newMatrix);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        //1戻り値をScilabに渡す

        AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;

 

        ReturnArguments(pvApiCtx);

 

        return 0;

}

64bitの場合、アドレスは8バイト整数で型はlong longです。ポインタにはこのアドレスの番地が格納されます。配列の場合、8バイトのdoubleだとアドレス番地は+8ずつ、1バイトのuint8(unsigned char)だとアドレス番地は+1バイトずつ、格納されていきます。そこでdoubleのアドレス番地を読み込んで1つずつ番地をずらしながらuint8として読み込んでいけば型変換ができます。

実際に試してみます。

--> table=['double2bytemex','double2byte';'single2bytemex','single2byte'];

 

--> ilib_build('typecast',table,['test04.c'],[]);

   ゲートウェイファイルを生成

   ローダファイルの生成

   Makefileの生成

   Makefile を実行中

   コンパイル test04.c

   コンパイル typecast.cpp

   コンパイル typecast.h

   コンパイル typecast.hxx

   共有ライブラリを構築中 (お待ちください)

   クリーナ・ファイルの生成

 

--> exec('loader.sce');

共有アーカイブをロードしました。

リンク完了

 

--> double2bytemex(3.14)

 ans  =

 

  31  133  235  81  184  30  9  64

 

 

--> single2bytemex(3.14)

 ans  =

 

  195  245  72  64

出力された数字はuint8です。尚、Scilabではfloat(single)が使えないので、内部でdoublesingleに型変換して出力しています。

 

非負の1バイトを浮動小数点に型変換する関数の作成

反対に、非負の1バイトから浮動小数点に変換する関数を作成し、test05.cという名前で保存しました。

#include "api_scilab.h"

#include <localization.h>//_(**)のときに必要?

#include <Scierror.h>//Scierrorを使うとき必要

#include <malloc.h>

 

int byte2double(char *fname, void* pvApiCtx)

{  

    //エラー表示用

        SciErr sciErr;

 

        //1変数

        int m = 0, n = 0;

        int *piAddressVar = NULL;

        unsigned char *matrixOfUnsignedChar = NULL;

 

        //1引数のcheck

        //address取得

        sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVar);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

        //整数で虚数でない

        if (!isIntegerType(pvApiCtx, piAddressVar) || isVarComplex(pvApiCtx, piAddressVar))

        {

                 Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), fname, 1);

                 return 0;

        }

        //uint8でない

        int iPrecision=0;//精度

        sciErr = getMatrixOfIntegerPrecision(pvApiCtx, piAddressVar, &iPrecision);

        // int8,int16,int32,int64はバイト数 1,2,4,8 uint8,uint16,uint32,uint6411,12,14,18となる

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

        if (iPrecision != 11)

        {

                 Scierror(999, _("Input argument must be uint8.\n"));

                 return 0;

        }

 

        //行列の取得

        sciErr = getMatrixOfUnsignedInteger8(pvApiCtx, piAddressVar, &m, &n, &matrixOfUnsignedChar);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        int i = 0;

        int row = 1, col = m * n / 8;

        double *p;

 

        //1戻り値

        double* newMatrix = NULL;

        newMatrix = (double*)malloc(sizeof(double*)*row*col);

 

        //引数と戻り値の数のcheck

        //string=double2hex(double)

        CheckInputArgument(pvApiCtx, 1, 1);//引数は1

        CheckOutputArgument(pvApiCtx, 1, 1);//戻り値は1

 

        for (i = 0; i < col; i++)

        {

                 p = (double*)&matrixOfUnsignedChar[i * 8];

                 newMatrix[i] = *p;

        }

 

        //1戻り値用行列のポインタ作成

        sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1,col,newMatrix);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        //1戻り値をScilabに渡す

        AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;

 

        ReturnArguments(pvApiCtx);

 

        return 0;

}

 

int byte2single(char *fname, void* pvApiCtx)

{

        //エラー表示用

        SciErr sciErr;

 

        //1変数

        int m = 0, n = 0;

        int *piAddressVar = NULL;

        unsigned char *matrixOfUnsignedChar = NULL;

 

        //1引数のcheck

        //address取得

        sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVar);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

        //整数で虚数でない

        if (!isIntegerType(pvApiCtx, piAddressVar) || isVarComplex(pvApiCtx, piAddressVar))

        {

                 Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), fname, 1);

                 return 0;

        }

        //uint8でない

        int iPrecision = 0;//精度

        sciErr = getMatrixOfIntegerPrecision(pvApiCtx, piAddressVar, &iPrecision);

        // int8,int16,int32,int64はバイト数 1,2,4,8 uint8,uint16,uint32,uint6411,12,14,18となる

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

        if (iPrecision != 11)

        {

                 Scierror(999, _("Input argument must be uint8.\n"));

                 return 0;

        }

 

        //行列の取得

        sciErr = getMatrixOfUnsignedInteger8(pvApiCtx, piAddressVar, &m, &n, &matrixOfUnsignedChar);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        int i = 0;

        int row = 1, col = m * n / 4;

        float *p; // floatにしてあとでdoubleにする

 

        //1戻り値

        double* newMatrix = NULL;

        newMatrix = (double*)malloc(sizeof(double*)*row*col);

 

        //引数と戻り値の数のcheck

        //string=double2hex(double)

        CheckInputArgument(pvApiCtx, 1, 1);//引数は1

        CheckOutputArgument(pvApiCtx, 1, 1);//戻り値は1

 

        for (i = 0; i < col; i++)

        {

                 p = (float*)&matrixOfUnsignedChar[i * 4];

                 newMatrix[i] = (double)*p;

        }

 

        //1戻り値用行列のポインタ作成

        sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1, col, newMatrix);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        //1戻り値をScilabに渡す

        AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;

 

        ReturnArguments(pvApiCtx);

 

        return 0;

}

試してみます。

最初にdynamic linkを切っておきます。

--> link

 ans  =

 

 typecast

 

 

--> ulink(0)

 

前回のライブラリ名typecastに追加する形でbuildし、実行してみます。

--> table=['double2bytemex','double2byte';'single2bytemex','single2byte';'byte2doublemex','byte2double';'byte2singlemex','byte2single']

 table  =

 

!double2bytemex  double2byte  !

!                             !

!single2bytemex  single2byte  !

!                             !

!byte2doublemex  byte2double  !

!                             !

!byte2singlemex  byte2single  !

 

 

--> ilib_build('typecast',table,['test04.c','test05.c'],[]);

   ゲートウェイファイルを生成

   ローダファイルの生成

   Makefileの生成

   Makefile を実行中

   コンパイル test04.c

   コンパイル test05.c

   コンパイル typecast.cpp

   コンパイル typecast.h

   コンパイル typecast.hxx

   共有ライブラリを構築中 (お待ちください)

   クリーナ・ファイルの生成

 

--> exec('loader.sce');

共有アーカイブをロードしました。

リンク完了

 

--> x=double2bytemex(3.14)

 x  =

 

  31  133  235  81  184  30  9  64

 

 

--> byte2doublemex(x)

 ans  =

 

   3.14

 

 

--> x=single2bytemex(3.14)

 x  =

 

  195  245  72  64

 

 

--> byte2singlemex(x)

 ans  =

 

   3.1400001

4バイトの浮動小数点だと精度が悪く、少数第7桁目に誤差が出てしまいました。

 

typecast関数の作成

Scilabではsingleは使えないの、それ抜きにしてMATLABtypecast関数もどきを作成しました。虚数には対応していません。以下のファイルをtest08.cという名前で保存しました。

#include "api_scilab.h"

 

#include <localization.h>//_(**)のときに必要?

#include <Scierror.h>//Scierrorを使うとき必要

#include <malloc.h>

#include <sciprint.h>

 

 

 

int typecast(char *fname, void* pvApiCtx)

 

{

        //エラー表示用

        SciErr sciErr;

 

        //1引数と第1戻り値

        int iPrecision = 0;//double

        int *p1 = NULL;

        int m = 0;//

        int n = 0;//

        double *matrixOfDouble, *Doubles;

        float *pf;

        char *matrixOfint8, *Int8s;

        short *matrixOfint16, *Int16s;

        int *matrixOfint32, *Int32s;

        unsigned char *matrixOfuint8, *Uint8s;

        unsigned short *matrixOfuint16, *Uint16s;

        unsigned int *matrixOfuint32, *Uint32s;

 

        //2引数 文字列の1×1の行列

        int *p2 = NULL;

        int m2 = 0;

        int n2 = 0;

        int *pstrlen = NULL;

        //char str[7];//6文字まで

        char **str;

 

        int i, j, k;

 

        //引数と戻り値のチェック

        CheckInputArgument(pvApiCtx, 2, 2);//引数は1

        CheckOutputArgument(pvApiCtx, 1, 1);//戻り値は1

        //1引数のcheck

        //address取得

        sciErr = getVarAddressFromPosition(pvApiCtx, 1, &p1);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        if (isVarComplex(pvApiCtx, p1))//虚数でない

        {

                 Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), fname, 1);

                 return 0;

        }

        //doubleで虚数でない

        if (isDoubleType(pvApiCtx, p1))//double

        {

                 sciErr = getMatrixOfDouble(pvApiCtx, p1, &m, &n, &matrixOfDouble);

        }

        else

        {

                 sciErr = getMatrixOfIntegerPrecision(pvApiCtx, p1, &iPrecision);

                 if (sciErr.iErr)

                 {

                         printError(&sciErr, 0);

                         return 0;

                 }

        }

 

        switch (iPrecision)

        {

                 case 0:

                         break;

            case 1:

                sciErr = getMatrixOfInteger8(pvApiCtx, p1, &m, &n, &matrixOfint8);

                     break;

                 case 2:

                         sciErr = getMatrixOfInteger16(pvApiCtx, p1, &m, &n, &matrixOfint16);

                         break;

                 case 4:

                         sciErr = getMatrixOfInteger32(pvApiCtx, p1, &m, &n, &matrixOfint32);

                         break;

                 case 11:

                         sciErr = getMatrixOfUnsignedInteger8(pvApiCtx, p1, &m, &n, &matrixOfuint8);

                         break;

                 case 12:

                         sciErr = getMatrixOfUnsignedInteger16(pvApiCtx, p1, &m, &n, &matrixOfuint16);

                         break;

                 case 14:

                         sciErr = getMatrixOfUnsignedInteger32(pvApiCtx, p1, &m, &n, &matrixOfuint32);

                         break;

                 default:

                         return 0;

        }

        //2引数のcheck

        //address取得

        sciErr = getVarAddressFromPosition(pvApiCtx, 2, &p2);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

        //1回目コール 文字行列の行数と列数を取得

        sciErr = getMatrixOfString(pvApiCtx, p2, &m2, &n2, NULL, NULL);//&m2&nの代わりにNULLを入れるとエラー

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        pstrlen = (int*)malloc(sizeof(int)*m2*n2);

        //2回目コール 各要素の文字長を取得

        sciErr = getMatrixOfString(pvApiCtx, p2, &m2, &n2, pstrlen, NULL);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

    str = (char**)malloc(sizeof(char*)*m2*n2);

        for (i = 0; i < m2*n2; i++)

        {

                 str[i] = (char*)malloc(sizeof(char)*(pstrlen[i] + 1));

        }

        //3回目コール 各要素の文字列を取得

        sciErr = getMatrixOfString(pvApiCtx, p2, &m2, &n2, pstrlen, str);

        if (sciErr.iErr)

        {

                 printError(&sciErr, 0);

                 return 0;

        }

 

        if (strcmp(str[0], "double") == 0)

        {               

                 k = m * n;

                 if (iPrecision>10)

                 {

                         k = m * n * (iPrecision - 10) / 8;

                 }

                 else if (iPrecision > 0)

                 {

                         k = m * n * iPrecision / 8;

                 }

 

                 Doubles = (double*)malloc(sizeof(double) * k);      

                 switch (iPrecision)

                 {

                 case 0:                          

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = matrixOfDouble[i];

                         }

                         break;

                 case 1:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = *((double*)&matrixOfint8[i * 8]);

                         }

                         break;

                 case 11:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = *((double*)&matrixOfuint8[i * 8]);

                         }

                         break;

                 case 2:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = *((double*)&matrixOfint16[i * 4]);

                         }

                         break;

                 case 12:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = *((double*)&matrixOfuint16[i * 4]);

                         }

                         break;

                 case 4:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = *((double*)&matrixOfint32[i * 2]);

                         }

                         break;

                 case 14:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = *((double*)&matrixOfuint32[i * 2]);

                         }

                         break;

                 default:

                         return 0;

                 }

                 sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1, k, Doubles);

        }

        else if (strcmp(str[0], "single") == 0)

        {

                 if (iPrecision>10)

                 {

                         k = m * n * (iPrecision - 10) / 4;

                 }

                 else if (iPrecision > 0)

                 {

                         k = m * n * iPrecision / 4;

                 }

                 else if (iPrecision == 0)

                 {

                         k = m * n * 2;

                 }

                 Doubles = (double*)malloc(sizeof(double)* k);

                 switch (iPrecision)

                 {

                 case 0:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  pf = (float*)(&matrixOfDouble[i / 2]);

                                  Doubles[i] = (double)*pf;

                                  Doubles[i + 1] = (double)*(pf+1);

                         }

                         break;

                 case 1:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = (double)*((float*)(&matrixOfint8[i * 4]));

                         }

                         break;

                 case 11:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = (double)*((float*)(&matrixOfuint8[i * 4]));

                         }

                         break;

                 case 2:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = (double)*((float*)(&matrixOfint16[i * 2]));

                         }

                         break;

                 case 12:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = (double)*((float*)(&matrixOfuint16[i * 2]));

                         }

                         break;

                 case 4:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = (double)*((float*)(&matrixOfint32[i]));

                         }

                         break;

                 case 14:

                         for (i = 0; i < k; i++)

                         {

                                  Doubles[i] = (double)*((float*)(&matrixOfuint32[i]));

                         }

                         break;

                 default:

                         return 0;

                 }

                 sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1, k, Doubles);

        }

        else if (strcmp(str[0], "int8") == 0)

        {

                 if (iPrecision>10)

                 {

                         k = m * n * (iPrecision - 10);

                 }

                 else if (iPrecision > 0)

                 {

                         k = m * n * iPrecision;

                 }

                 else if (iPrecision == 0)

                 {

                         k = m * n * 8;

                 }

                 Int8s = (char*)malloc(sizeof(char) * k);

                 switch (iPrecision)

                 {

                 case 0:

                         for (i = 0; i < k; i = i + 8)

                         {

                                  for (j = 0; j < 8; j++)

                                  {

                                          Int8s[i+j] = *((char*)&matrixOfDouble[i / 8]+j);

                                  }                                

                         }

                         break;

                 case 1:

                         for (i = 0; i < k; i++)

                         {

                                  Int8s[i] = matrixOfint8[i];

                         }

                         break;

                 case 11:

                         for (i = 0; i < k; i++)

                         {

                                  Int8s[i] = *((char*)(&matrixOfuint8[i]));

                         }

                         break;

                 case 2:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  Int8s[i] = *((char*)(&matrixOfint16[i / 2]));

                                  Int8s[i + 1] = *((char*)(&matrixOfint16[i / 2]) + 1);

                         }

                         break;

                 case 12:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  Int8s[i] = *((char*)(&matrixOfuint16[i / 2]));

                                  Int8s[i + 1] = *((char*)(&matrixOfuint16[i / 2]) + 1);

                         }

                         break;

                 case 4:

                         for (i = 0; i < k; i = i + 4)

                         {

                                  for (j = 0; j < 4; j++)

                                  {

                                          Int8s[i + j] = *((char*)(&matrixOfint32[i / 4]) + j);

                                  }

                         }

                         break;

                 case 14:

                         for (i = 0; i < k; i = i + 4)

                         {

                                  for (j = 0; j < 4; j++)

                                  {

                                          Int8s[i + j] = *((char*)(&matrixOfuint32[i / 4]) + j);

                                  }

                         }

                         break;

                 default:

                         return 0;

                 }

                 sciErr = createMatrixOfInteger8(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1, k, Int8s);

        }

        else if (strcmp(str[0], "uint8") == 0)

        {

                 if (iPrecision>10)

                 {

                         k = m * n * (iPrecision - 10);

                 }

                 else if (iPrecision > 0)

                 {

                         k = m * n * iPrecision;

                 }

                 else if (iPrecision == 0)

                 {

                         k = m * n * 8;

                 }

                 Uint8s = (unsigned char*)malloc(sizeof(unsigned char)* k);

                 switch (iPrecision)

                 {

                 case 0:

                         for (i = 0; i < k; i = i + 8)

                         {

                                  for (j = 0; j < 8; j++)

                                  {

                                          Uint8s[i + j] = *((unsigned char*)&matrixOfDouble[i / 8] + j);

                                  }

                         }

                         break;

                 case 1:

                         for (i = 0; i < k; i++)

                         {

                                  Uint8s[i] = *((unsigned char*)(&matrixOfint8[i]));

                         }

                         break;

                 case 11:

                         for (i = 0; i < k; i++)

                         {

                                  Uint8s[i] = *((unsigned char*)(&matrixOfuint8[i]));

                         }

                         break;

                 case 2:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  Uint8s[i] = *((unsigned char*)(&matrixOfint16[i / 2]));

                                  Uint8s[i + 1] = *((unsigned char*)(&matrixOfint16[i / 2]) + 1);

                         }

                         break;

                 case 12:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  Uint8s[i] = *((unsigned char*)(&matrixOfuint16[i / 2]));

                                  Uint8s[i + 1] = *((unsigned char*)(&matrixOfuint16[i / 2]) + 1);

                         }

                         break;

                 case 4:

                         for (i = 0; i < k; i = i + 4)

                         {

                                  for (j = 0; j < 4; j++)

                                  {

                                          Uint8s[i + j] = *((unsigned char*)(&matrixOfint32[i / 4]) + j);

                                  }

                         }

                         break;

                 case 14:

                         for (i = 0; i < k; i = i + 4)

                         {

                                  for (j = 0; j < 4; j++)

                                  {

                                          Uint8s[i + j] = *((unsigned char*)(&matrixOfuint32[i / 4]) + j);

                                  }

                         }

                         break;

                 default:

                         return 0;

                 }

                 sciErr = createMatrixOfUnsignedInteger8(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1, k, Uint8s);

        }

        else if (strcmp(str[0], "int16") == 0)

        {

                 if (iPrecision>10)

                 {

                         k = m * n * (iPrecision - 10) / 2;

                 }

                 else if (iPrecision > 0)

                 {

                         k = m * n * iPrecision / 2;

                 }

                 else if (iPrecision == 0)

                 {

                         k = m * n * 8 / 2;

                 }

                 Int16s = (short*)malloc(sizeof(short)* k);

                 switch (iPrecision)

                 {

                 case 0:

                         for (i = 0; i < k; i = i + 4)

                         {

                                  for (j = 0; j < 4; j++)

                                  {

                                          Int16s[i + j] = *((short*)&matrixOfDouble[i / 4    ] + j);

                                  }

                         }

                         break;

                 case 1:

                         for (i = 0; i < k; i++)

                         {

                                  Int16s[i] = *((short*)(&matrixOfint8[i * 2]));

                         }

                         break;

                 case 11:

                         for (i = 0; i < k; i++)

                         {

                                  Int16s[i] = *((short*)(&matrixOfuint8[i * 2]));

                         }

                         break;

                 case 2:

                         for (i = 0; i < k; i++)

                         {

                                  Int16s[i] = *((short*)(&matrixOfint16[i]));

                         }

                         break;

                 case 12:

                         for (i = 0; i < k; i++)

                         {

                                  Int16s[i] = *((short*)(&matrixOfuint16[i]));

                         }

                         break;

                 case 4:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  Int16s[i] = *((short*)(&matrixOfint32[i / 2]));

                                  Int16s[i + 1] = *((short*)(&matrixOfint32[i / 2]) + 1);

                         }

                         break;

                 case 14:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  Int16s[i] = *((short*)(&matrixOfuint32[i / 2]));

                                  Int16s[i + 1] = *((short*)(&matrixOfuint32[i / 2]) + 1);

                         }

                         break;

                 default:

                         return 0;

                 }

                 sciErr = createMatrixOfInteger16(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1, k, Int16s);

        }

        else if (strcmp(str[0], "uint16") == 0)

        {

                 if (iPrecision>10)

                 {

                         k = m * n * (iPrecision - 10) / 2;

                 }

                 else if (iPrecision > 0)

                 {

                         k = m * n * iPrecision / 2;

                 }

                 else if (iPrecision == 0)

                 {

                         k = m * n * 8 / 2;

                 }

                 Uint16s = (unsigned short*)malloc(sizeof(unsigned short)* k);

                 switch (iPrecision)

                 {

                 case 0:

                         for (i = 0; i < k; i = i + 4)

                         {

                                  for (j = 0; j < 4; j++)

                                  {

                                          Uint16s[i + j] = *((unsigned short*)&matrixOfDouble[i / 4] + j);

                                  }

                         }

                         break;

                 case 1:

                         for (i = 0; i < k; i++)

                         {

                                  Uint16s[i] = *((unsigned short*)(&matrixOfint8[i * 2]));

                         }

                         break;

                 case 11:

                         for (i = 0; i < k; i++)

                         {

                                  Uint16s[i] = *((unsigned short*)(&matrixOfuint8[i * 2]));

                         }

                         break;

                 case 2:

                         for (i = 0; i < k; i++)

                         {

                                  Uint16s[i] = *((unsigned short*)(&matrixOfint16[i]));

                         }

                         break;

                 case 12:

                         for (i = 0; i < k; i++)

                         {

                                  Uint16s[i] = *((unsigned short*)(&matrixOfuint16[i]));

                         }

                         break;

                 case 4:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  Uint16s[i] = *((unsigned short*)(&matrixOfint32[i / 2]));

                                  Uint16s[i + 1] = *((unsigned short*)(&matrixOfint32[i / 2]) + 1);

                         }

                         break;

                 case 14:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  Uint16s[i] = *((unsigned short*)(&matrixOfuint32[i / 2]));

                                  Uint16s[i + 1] = *((unsigned short*)(&matrixOfuint32[i / 2]) + 1);

                         }

                         break;

                 default:

                         return 0;

                 }

                 sciErr = createMatrixOfUnsignedInteger16(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1, k, Uint16s);

        }

        else if (strcmp(str[0], "int32") == 0)

        {

                 if (iPrecision>10)

                 {

                         k = m * n * (iPrecision - 10) / 4;

                 }

                 else if (iPrecision > 0)

                 {

                         k = m * n * iPrecision / 4;

                 }

                 else if (iPrecision == 0)

                 {

                         k = m * n * 8 / 4;

                 }

                 Int32s = (int*)malloc(sizeof(int)* k);

                 switch (iPrecision)

                 {

                 case 0:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  Int32s[i] = *((int*)&matrixOfDouble[i / 2]);

                                  Int32s[i + 1] = *((int*)&matrixOfDouble[i / 2] + 1);

                         }

                         break;

                 case 1:

                         for (i = 0; i < k; i++)

                         {

                                  Int32s[i] = *((int*)(&matrixOfint8[i * 4]));

                         }

                         break;

                 case 11:

                         for (i = 0; i < k; i++)

                         {

                                  Int32s[i] = *((int*)(&matrixOfuint8[i * 4]));

                         }

                         break;

                 case 2:

                         for (i = 0; i < k; i++)

                         {

                                  Int32s[i] = *((int*)(&matrixOfint16[i * 2]));

                         }

                         break;

                 case 12:

                         for (i = 0; i < k; i++)

                         {

                                  Int32s[i] = *((int*)(&matrixOfuint16[i * 2]));

                         }

                         break;

                 case 4:

                         for (i = 0; i < k; i++)

                         {

                                  Int32s[i] = *((int*)(&matrixOfint32[i]));

                         }

                         break;

                case 14:

                         for (i = 0; i < k; i++)

                         {

                                  Int32s[i] = *((int*)(&matrixOfuint32[i]));

                         }

                         break;

                 default:

                         return 0;

                 }

                 sciErr = createMatrixOfInteger32(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1, k, Int32s);

        }

        else if (strcmp(str[0], "uint32") == 0)

        {

                 if (iPrecision>10)

                 {

                         k = m * n * (iPrecision - 10) / 4;

                 }

                 else if (iPrecision > 0)

                 {

                         k = m * n * iPrecision / 4;

                 }

                 else if (iPrecision == 0)

                 {

                         k = m * n * 8 / 4;

                 }

                 Uint32s = (unsigned int*)malloc(sizeof(unsigned int)* k);

                 switch (iPrecision)

                 {

                 case 0:

                         for (i = 0; i < k; i = i + 2)

                         {

                                  Uint32s[i] = *((unsigned int*)&matrixOfDouble[i / 2]);

                                  Uint32s[i + 1] = *((unsigned int*)&matrixOfDouble[i / 2] + 1);

                         }

                         break;

                 case 1:

                         for (i = 0; i < k; i++)

                         {

                                  Uint32s[i] = *((int*)(&matrixOfint8[i * 4]));

                         }

                         break;

                 case 11:

                         for (i = 0; i < k; i++)

                         {

                                  Uint32s[i] = *((int*)(&matrixOfuint8[i * 4]));

                         }

                         break;

                 case 2:

                         for (i = 0; i < k; i++)

                         {

                                  Uint32s[i] = *((int*)(&matrixOfint16[i * 2]));

                         }

                         break;

                 case 12:

                         for (i = 0; i < k; i++)

                         {

                                  Uint32s[i] = *((int*)(&matrixOfuint16[i * 2]));

                         }

                         break;

                 case 4:

                         for (i = 0; i < k; i++)

                         {

                                  Uint32s[i] = *((int*)(&matrixOfint32[i]));

                         }

                         break;

                 case 14:

                         for (i = 0; i < k; i++)

                         {

                                  Uint32s[i] = *((int*)(&matrixOfuint32[i]));

                         }

                         break;

                 default:

                         return 0;

                 }

                 sciErr = createMatrixOfUnsignedInteger32(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1, k, Uint32s);

        }

        else

        {

                 return 0;

        }

        //1戻り値をScilabに渡す

        AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;

        ReturnArguments(pvApiCtx);

 

        return 0;

}

ビルドしてリンクして試してみます。

--> ilib_build('lib08',['typecastmex','typecast'],['test08.c'],[]);

   ゲートウェイファイルを生成

   ローダファイルの生成

   Makefileの生成

   Makefile を実行中

   コンパイル lib08.cpp

   コンパイル lib08.h

   コンパイル lib08.hxx

   コンパイル test08.c

   共有ライブラリを構築中 (お待ちください)

   クリーナ・ファイルの生成

 

--> exec('loader.sce');

共有アーカイブをロードしました。

リンク完了

 

--> typecastmex(int32([1078523331,-1078655871]),'single')

 ans  =

 

   3.1400001  -1.4141999