Storing doubles in the smallest integer class for which they fit without changing their value?

3 views (last 30 days)
I am trying to create function that accepts an input array, A, and converts it to the smallest integer class for which it can be stored without changing the information in the matrix. If the matrix does not have any negative numbers it needs to be converted to the smallest possible unsigned integer type. Lastly, if none of the integer types are suitable, the matrix is returned without changing.
I am super new to MATLAB, so I hardly know all the built-in functions to make this code easy, nor do I really understand how MATLAB stores the information, but I have attached my code attempt below.
function smallint = store_small(A)
A = [];
[rows, cols] = size(A);
for ii = 1:rows
for jj = 1:cols
if any(A(ii, jj)) < 0
if A(ii, jj) >= (-2)^7 && A(ii, jj) <= (2^7)-1
smallint = int8(A);
elseif A(ii, jj) >= (-2)^15 && A(ii, jj) <= (2^15)-1
smallint = int16(A);
elseif A(ii, jj) >= (-2)^31 && A(ii, jj) <= (2^31)-1
smallint = int32(A);
elseif A(ii, jj) >= (-2)^53 && A(ii, jj) <= (2^53)-1
smallint = int64(A);
else
smallint = A;
end
else
if A(ii, jj) <= (2^8)-1
smallint = unit8(A);
elseif A(ii, jj) <= (2^16)-1
smallint = unit16(A);
elseif A(ii, jj) <= (2^32)-1
smallint = unit32(A);
elseif A(ii, jj) <= (2^64)-1
smallint = unit64(A);
else
smallint = A;
end
end
end
end
end
As you can tell, I took the time to type out all of those inequalities which is probably a rather monotonous way to do it for the more advanced. Either way, I'm hoping someone can tell me where I'm going wrong.
  • my function does not return a matrix. I'm not sure if this is due to the ; or just because the code is not right.
  • my function also gives an incorrect output for the input zero.
  • i did not add second conditions to each "elseif" statement when dealing with A values that were all greater than zero because I think MATLAB checks the elseif statements one at a time and if it is true, spits out the respective value of that elseif statment and stops. I could be wrong though.
Please help me :) Thanks.

Accepted Answer

James Tursa
James Tursa on 3 Apr 2020
Edited: James Tursa on 3 Apr 2020
Some hints:
Don't use loops, use vectorized code to figure out which integer size works.
intmax(type) gives you the largest value for the type. E.g., intmax('int8') or intmax('uint32'). Use these for your range checks. Also note that signed integers use 2's complement so the range is not exactly symmetric about 0 if you care for this detail. E.g., the range of a int8 is -128 to 127.
Or, if processing time is not an issue, simple brute force would be easy to code. E.g.,
if( any(A(:)<0) )
smallint = int8(A);
if( isequal(A,smallint) )
return
end
smallint = int16(A);
if( isequal(A,smallint) )
return
end
etc.
else
smallint = uint8(A);
if( isequal(A,smallint) )
return
end
smallint = uint16(A);
if( isequal(A,smallint) )
return
end
etc.
end
smallint = A;
You could even put the brute force stuff in a loop.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!