How to convert /map uint16 to int16 maintaining the dynamic range so that [0] and [2^16-1] in uint16 beomes [-2^15] and [2^15-1] without going through double

25 Ansichten (letzte 30 Tage)
I would like to convert my uint16 values to int16 values amd maintain the dynamic range. All my attempts with typecast and cast still map value 0 (uint16) to 0 (int16). I would like it to map 0 (uint16) directly to -2^15 (int16). I need to convert a rather large dataset so I would like to circumvent doing to double or single if I can.
The data comes from fread and if I can do the mapping there directly then that would be even better. This is what I use now to read the data:
Data = fread(fid,[m n],'uint16=>uint16')';
Ive tried asking for 'uint16=>int16', but that also cuts the data
  1 Kommentar
Micke Malmström
Micke Malmström am 2 Feb. 2024
Bearbeitet: Micke Malmström am 2 Feb. 2024
% Example uint16 data
uint16Data = uint16([0, 2^16-1]);
% Map uint16 to int16
int16Data = int16(uint16Data - 2^15); % here is where the problem lies and I cant figure out how to circumvent going through double or single...
% Display the results
disp(['Original uint16 data: ', num2str(uint16Data)]);
Original uint16 data: 0 65535
disp(['Mapped int16 data: ', num2str(int16Data)]); % my desired result here is Mapped int16 data: -32768 32767
Mapped int16 data: 0 32767

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Stephen23
Stephen23 am 2 Feb. 2024
Bearbeitet: Stephen23 am 2 Feb. 2024
inp = uint16([-Inf,pi,Inf])
inp = 1×3
0 3 65535
Method one: use INT32 for the intermediate values:
off = int32(intmin('int16'));
out = int16(int32(inp)+off)
out = 1×3
-32768 -32765 32767
Method two: convert from two's complement to offset binary, which you can then simply TYPECAST into INT16:
out = typecast(bitset(inp,16,1-bitget(inp,16)),'int16')
out = 1×3
-32768 -32765 32767

Weitere Antworten (1)

Bruno Luong
Bruno Luong am 3 Feb. 2024
Bearbeitet: Bruno Luong am 3 Feb. 2024
If you have C compiler this simple mex file will do the job:
/**************************************************************************
* Matlab Mex file castint16.C
Convert uint16 to int16 by adding 2^15 in 2-complement binary coding
Example:
a = uint16([0 2^16-1])
b = castint16(a)
will return
1×2 int16 row vector
-32768 32767
Compile:
mex -R2018a castint16.c
*************************************************************************/
#include "mex.h"
#include "matrix.h"
#define A prhs[0]
#define B plhs[0]
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
size_t i, n;
mxUint16 *a, *b;
if (nrhs!=1)
mexErrMsgTxt("castint16 missing input argument");
/* n = numel(A) */
n = mxGetNumberOfElements(A);
if (mxGetClassID(A) == mxUINT16_CLASS) {
a = mxGetUint16s (A);
B = mxCreateNumericMatrix(mxGetM(A), mxGetN(A), mxINT16_CLASS, mxREAL);
b = mxGetInt16s(B);
for (i = 0; i < n; i++)
b[i] = a[i] + 0x8000;
} else
mexErrMsgTxt("castint16 suports only UINT16 input");
}

Kategorien

Mehr zu Cell Arrays finden Sie in Help Center und File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by