How to wrap on overflow when transfer a double to integer

I would like to transfer a double to an unsigned integer, specific 16-bit integer, with WRAP on overflow in Matlab coding.
I currently use, but it SATURATEs on overflow
y = uint16(x);
Does anyone have solution?

 Accepted Answer

You could use:
y = mod(x,double(intmax('uint16'))+1);
But, if x is too large so that eps(x) > 1 the result might be somewhat meaningless.

7 Comments

Thanks James Tursa for your suggestion.
I also would like to avod use MOD function for DOUBLE format.
I have tried to transfer double uint32 format, then use the MOD function. However, I would like to find a better solution.
Why don't you like MOD? That's essentially the functionality you are trying to reproduce, so why avoid it? I don't understand this restriction. I suppose you could call a mex function and have the C compiler do a natural conversion, but this seems unnecessary in this case.
Hi James Tursa,
I am going to implement code for Real Time application. I have tested and the MOD function take alot of time to execute. I need a solution which should be fast for Real Time.
Thank you for your suggestion. I am going to have a look on MEX file function.
Kind Regarcds
The guts of the mex code is simply
double d;
unsigned short u; /* or whatever type your compiler will support for 16-bit unsigned integer */
:
u = d;
Maybe let the coder generate the saturation code that you don't want, and then go in and manually change it to the above one-liner.
Thank you for your advice.
But there is an error when I did. What was I wrong?
The 'Double2Uint.c' file is
double d;
unsigned short u;
u = d;
In Matlab, I type
mex Double2Uint.c
Then it showed errors.
>> mex Double2Uint.c
Building with 'MinGW64 Compiler (C)'.
Error using mex
C:\---\Documents\MATLAB\Double2Uint.c:4:1: warning: data
definition has no type or storage class
u = d;
^
C:\---\Documents\MATLAB\Double2Uint.c:4:1: warning: type defaults
to 'int' in declaration of 'u' [-Wimplicit-int]
C:\---\Documents\MATLAB\Double2Uint.c:4:1: error: conflicting
types for 'u'
C:\---\Documents\MATLAB\Double2Uint.c:2:16: note: previous
declaration of 'u' was here
unsigned short u;
^
C:\---\Documents\MATLAB\Double2Uint.c:4:5: error: initializer
element is not constant
u = d;
^
Could you give me more detail.
Thanks
Sorry. I just gave you the gist of the code, not the complete code. A complete mex file would be:
(EDIT: Updated code to account for mwSize possibly being different size than size_t)
/* Convert a full real double input to a uint16 output with natural mod conversion */
#include "mex.h"
#include <stdint.h>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *d;
uint16_t *u;
size_t n, ndims;
size_t *sdims;
mwSize *mdims;
if( nrhs != 1 || !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) ) {
mexErrMsgTxt("Need exactly one full real double input");
}
if( nlhs > 1 ) {
mexErrMsgTxt("Too many outputs");
}
ndims = mxGetNumberOfDimensions(prhs[0]);
mdims = (mwSize *) mxGetDimensions(prhs[0]);
sdims = (size_t *) mxMalloc(ndims*sizeof(*sdims));
for( n = 0; n<ndims; n++ ) {
sdims[n] = mdims[n];
}
plhs[0] = mxCreateUninitNumericArray(ndims, sdims, mxUINT16_CLASS, mxREAL);
mxFree(sdims);
d = (double *) mxGetData(prhs[0]);
u = (uint16_t *) mxGetData(plhs[0]);
n = mxGetNumberOfElements(prhs[0]);
while( n-- ) {
*u++ = *d++;
}
}
Dear James Tursa,
Thank you for your help. It works.
Regards

Sign in to comment.

More Answers (0)

Categories

Products

Asked:

on 30 Jan 2020

Commented:

on 1 Feb 2020

Community Treasure Hunt

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

Start Hunting!