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?

 Réponse acceptée

James Tursa
James Tursa le 30 Jan 2020
Modifié(e) : James Tursa le 30 Jan 2020
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 commentaires

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.
James Tursa
James Tursa le 31 Jan 2020
Modifié(e) : James Tursa le 31 Jan 2020
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
James Tursa
James Tursa le 31 Jan 2020
Modifié(e) : James Tursa le 31 Jan 2020
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
James Tursa
James Tursa le 31 Jan 2020
Modifié(e) : James Tursa le 31 Jan 2020
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

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Operators and Elementary Operations dans Centre d'aide et File Exchange

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by