Precision lost when combining Int32 integers with single precision numerical numbers

6 views (last 30 days)
I have a column data A composed of Int32 numbers, and another column data B composed of single precision numbers. When I try to put them into one array C, my single precision numbers were botchered into integers.
C = [A, B];
Why is Matlab set up this way? Due to the loss of precision, my final calcualted values are way off. It took me quite some time to find out this is the reason.

Accepted Answer

John D'Errico
John D'Errico on 21 Jun 2025
Why is MATLAB set up this way? Because you can't please all of the people, all of the time. Suppose a numeric vector could have elements that are all different different numeric classes. Something like:
X = [pi, single(2.1), uint16(3)]
X = 1×3
3 2 3
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
whos X
Name Size Bytes Class Attributes X 1x3 6 uint16
etc. X will be a UINT16 by default here. But if the elements could retain their class information (not in the form of a cell array, which DOES retain the class information for each element), then any computation would be come IMMENSELY SLOW.
A huge benefiit of MATLAB is it runs blazingly fast when doing double precision computation, especially on large arrays. But if the code needed to check each element, and deal with the class of that number, then it would not be at all fast. And then almost everyone would be unhappy. As such, MATLAB is designed to store all numeric vectors using one class. concatenation operators make the decision which class to use, based on some simple rules.
So what happened to you?
In your case, you were combining int32 numbers with singles, by way of concatenation (horzcat)
Y1 = [int32(2), single(3.2)]
Y1 = 1×2
2 3
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
whos Y1
Name Size Bytes Class Attributes Y1 1x2 8 int32
The rule is that when you concatenate integers and singles together, you get an integer result.
If you really want to retain the information about each element, then you needed to use a cell array.
Z = {int32(2), single(3.2)}
Z = 1×2 cell array
{[2]} {[3.2000]}
As you can see, MATLAB now retains all the information you want for each element. The problem is, you can't do numerical operations using cell arrays.

More Answers (3)

Walter Roberson
Walter Roberson on 21 Jun 2025

The general rule is that when you combine numbers of two different types, that the result is the type that is considered more restricted. Integer is considered more restrictive than float


Matt J
Matt J on 21 Jun 2025
Edited: Matt J on 22 Jun 2025
I wasn't there when the decision was made, but I suspect it would be because in Matlab, numeric literals are always double floats. That goes back to the origins of Matlab, before integer types like int32 type were even introduced.
Once you're locked in with literals that are always double, it becomes inconvenient to prioritize precision. If the rule was to promote the lower precision operand to higher precision, then you would get an automatic explosion in RAM usage every time you did the simplest operations between large integer arrays and literal scalars, e.g.,.
A=int8(5000); %integer
C=A+1;
You could avoid this by remembering to convert your literal scalars, as in,
C=A+int8(1)
but not only is this incredibly cumbersome, it would also have forced people to rewrite their old code from before the days when integers were introduced.

Umar
Umar on 21 Jun 2025

Hi @Leon,

I read your comments and Hope interpret them carefully. In MATLAB, when you create an array that combines different data types, it attempts to promote all elements to a common type that can accommodate all values without loss of information. Since both Int32 and single types occupy 4 bytes, MATLAB defaults to converting the entire array to the type that is capable of representing all elements. In this case, it promotes to Int32, causing your single-precision floating-point numbers to lose their fractional parts and be represented as integers.

Here’s a deeper look at how this works:

1. Data Types in MATLAB Int32: A 32-bit signed integer that can represent whole numbers from -2,147,483,648 to 2,147,483,647.

Single: A 32-bit floating-point number that can represent a much wider range of values but includes fractions.

2. Array Concatenation Behavior When concatenating arrays like [A, B], MATLAB checks the types of both arrays. Since A is Int32 and B is single, it opts for Int32 for the entire resulting array C. The conversion effectively truncates any decimal portion of your single-precision numbers in B, leading to inaccuracies in further calculations.

Solutions and Recommendations

To address this issue effectively, consider the following approaches:

1. Explicit Type Conversion: Before concatenating your arrays, convert both arrays to a common type that preserves precision. For example:

C = [int32(A), single(B)];

This ensures that both arrays are treated as single-precision floating points in the resulting array.

2. Using Cell Arrays: If maintaining different data types is essential for your application, consider using cell arrays:

C = {A, B};

This allows you to keep the data types separate but still access them together.

3. Review Data Types Before Operations: Always check the data types using the class ( ) function before performing operations that combine different types. This can prevent unexpected behavior during calculations.

Hope this helps.

  9 Comments

Sign in to comment.

Tags

Products


Release

R2024b

Community Treasure Hunt

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

Start Hunting!