型変換の関数作成
ある書式のバイナリデータの読み書きしたいと思います。
自分は、ファイルを全部をuint8で読み込んで、MATLABのtypecast関数で試行錯誤することが多いです。
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は正負の符号sign、fは仮数部fraction、eは指数部exponentです。
3.14は4バイト浮動小数点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
0xは16進数を意味します。尚、NeuromagのFIFFファイルはbig endian(大きい桁から記載する)になっています。
順序が逆になりますので上記の場合は
0x00000028B5AFFB48
= 0x40 = 64
0x00000028B5AFFB49
= 0x48 = 72
0x00000028B5AFFB4A
= 0xF5 = 245
0x00000028B5AFFB4B
= 0xC3 = 195
等となります。
同様にdoubleを見ていきます。8バイトの浮動小数点は
で表されます。
3.14はdoubleでは
01000000
00001001 00011110 10111000 01010001 11101011 10000101
00011111
となります。符号部1bit、指数部11bit、仮数部52bitです。指数部の引き算はfloatの127と異なり、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となります。
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で虚数でない Scilabでsingleは使えないので・・・
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)が使えないので、内部でdoubleをsingleに型変換して出力しています。
反対に、非負の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,uint64は11,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,uint64は11,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桁目に誤差が出てしまいました。
Scilabではsingleは使えないの、それ抜きにしてMATLABのtypecast関数もどきを作成しました。虚数には対応していません。以下のファイルを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