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

조회 수: 1 (최근 30일)
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.

채택된 답변

James Tursa
James Tursa 2020년 4월 3일
편집: James Tursa 2020년 4월 3일
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.
  댓글 수: 2
Steven Lord
Steven Lord 2020년 4월 3일
The cast function will be particularly helpful if you want to loop over types. [cast and typecast are different; you want cast.]

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by