The single function is not behaving as expected
Show older comments
I'm trying to use single to save disk space because my files are very large. I know it could affect the precision if my numbers have many places after the decimal point. However, it is altering my integers as well.
>> single(340580097)
ans =
340580096.00
Is this a bug?
Accepted Answer
More Answers (1)
"However, it is altering my integers as well."
Then use an integer type of sufficient size to store those values; this would use the least possible memory.
8 Comments
d1 = 340580097
d2 = single(d1)
d3 = int32(d1)
whos
Under that approach, what should be the result of
single([pi,340580097]) % ?
Should the first element be converted to int32 just to preserve the value of the second element?
If all of the data are integer values, why not just convert to an integer type, i.e., why use single at all?
Is there a reason Matlab can not program the single() function so that it can automatically identify large integers and use int32 instead?
You could write your own function that converts an input to its most memory efficient type, something along the lines of the example below,
A = [3000, 100.5]
B= [340580097,340580100];
Ac=compress(A);
Bc=compress(B);
whos A B Ac Bc
isequal(A,Ac)
isequal(B,Bc)
However, you now have the problem that operations you previously took for granted might break,
C=A.*B
Cc=Ac.*Bc
The bottom line is, all programming languages require you to plan ahead what data type your variables need to be, and what type they will need to transform into, based on the computations you intend to perform. Or, you can just accept liberal use of RAM and keep everything as doubles.
function A=compress(A)
A=feval(best_numeric_class(A), A);
end
function T = best_numeric_class(A)
%BEST_NUMERIC_CLASS Determine the minimal-lossless MATLAB numeric class for A.
%
% T = best_numeric_class(A) returns a character vector like 'uint8',
% 'int16', 'single', 'double', etc., selecting the smallest class that
% can represent A exactly (no precision loss).
%
% Works for: logical, integer classes, floating classes, and real/complex.
% Logical stays logical
if islogical(A)
T = 'logical';
return;
end
% Complex -> must remain floating (integer classes cannot represent imag parts)
if ~isreal(A)
% Check whether single is sufficient
if all(single(A) == A, 'all')
T = 'single';
else
T = 'double';
end
return;
end
% If already integer class, leave unchanged
if isinteger(A)
T = class(A);
return;
end
% For floating-point inputs:
% 1. Check if all values are integer-valued
if all(A == floor(A), 'all') && all(isfinite(A), 'all')
xmin = min(A(:));
xmax = max(A(:));
% Unsigned range?
if xmin >= 0
if xmax <= intmax('uint8'), T = 'uint8';
elseif xmax <= intmax('uint16'), T = 'uint16';
elseif xmax <= intmax('uint32'), T = 'uint32';
else, T = 'uint64';
end
else
% Signed range
if xmin >= intmin('int8') && xmax <= intmax('int8'), T = 'int8';
elseif xmin >= intmin('int16') && xmax <= intmax('int16'),T = 'int16';
elseif xmin >= intmin('int32') && xmax <= intmax('int32'),T = 'int32';
elseif xmin >= intmin('int64') && xmax <= intmax('int64'),T = 'int64';
else, T = 'double'; % Values exceed int64 range
end
end
return;
end
% 2. Floating-point but not integer-valued:
% Test whether single precision is exactly sufficient
if all(single(A) == A, 'all')
T = 'single';
else
T = 'double';
end
end
Hi Matt,
Can you expand on this comment "(integer classes cannot represent imag parts)" in the context of this example
int32(100 + 110i)
Matt J
on 22 Nov 2025
No, I have no explanation for that. I didn't write the code. But feel free to modify as you see fit.
Steven Lord
on 22 Nov 2025
Is there a reason Matlab can not program the single() function so that it can automatically identify large integers and use int32 instead?
If you order a hamburger at a restaurant, would you be surprised / angry / insulted if the waiter looked at you and decided to serve you a salad instead?
To answer your question directly, there's no technical reason preventing MATLAB from doing that.
But if you explicitly ask MATLAB for a single precision value, I think most of our users would be very surprised to get something returned from that call to single that wasn't a single precision value. Users would report that as a silent wrong answer bug (the most severe type of bug, worse in many ways than MATLAB crashing; at least if MATLAB crashes it's obvious something went wrong) the second it went out the door in the Prerelease.
If a developer proposed making that change, most of the people reviewing that proposed change (and I would almost certainly be asked to review it, and this would be my review) would give it an OMDB (aka "You're shipping this Over My Dead Body.")
"Is there a reason Matlab can not program the single() function so that it can automatically identify large integers and use int32 instead?"
Yes, there are very good reasons:
1) you would force single() to be sloooooow. Instead of simply converting to one homogenous array (which can be preallocated by the MATLAB engine and then filled out with the values) you would force the MATLAB engine to either a) use a heterogenous array (i.e. container array) which is much slower to access OR b) parse all values into one array until it gets to a value which does not "fit" at which point it needs to create a new array and copy all of the existing homogenous array into a new memory location and then continue OR c) perform some other so-far-undefined-behavior. All of these will be significantly slower than using one homogenous array.
2) you would break an enormous amount of existing code. If single() could return int32, uint32, single, or any other type depending on input values, then every single line of code that calls single() would need defensive type checking. Consider:
data = single(userInput);
result = data * 0.5; % This breaks if data is int32!
Your proposal would break billions of lines of existing MATLAB code that reasonably expects single() to return single. The entire language's type system would become unreliable, calling external libraries and compiled code would be extremely fragile. Functions must have predictable return types, otherwise composition of operations becomes impossible.
3) Dispatch/overloading nightmare: MATLAB uses dynamic dispatch based on argument types. If single() returns different types based on values rather than input types, you break fundamental language semantics. Consider:
function process(x)
y = single(x);
% What methods are available on y?
% What operations are valid?
% This becomes undecidable without runtime value inspection
end
Method resolution, operator overloading, and function dispatch all assume type stability within a given code path. Value-dependent type returns would require the JIT compiler to give up all optimizations, making ALL MATLAB code significantly slower, not just single().
4) The documentation would be an opaque nightmare: "Returns single, unless the value is an integer that doesn't fit in single precision, in which case it returns int32, unless it's negative and too large, then int64, unless it is complex in which case return a unicorn..."
As Steven Lord described, explicitly requesting one thing and being given something completely different is a guarantee that the function is broken, not improved. Every function call site would need type guards. Generic algorithms would be impossible. Code review would require analyzing every possible value path to determine runtime types. This isn't "helpful automation," it's the destruction of language predictability - the very foundation that makes programming possible.
Categories
Find more on Logical 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!