How do operations on nondouble values in MATLAB differ from those in C?

14 views (last 30 days)
I would like more information about how the behavior of nondouble values in MATLAB differs from those in C.

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 18 Oct 2013
There are five main ways that nondouble arithmetic in MATLAB differs from that in C. These five differences are detailed below with examples. Note that points 3 and 4 apply to both single precision mixed with double, as well as to integer mixed with double. For point 4, however, the difference is much more subtle with single arithmetic than with integer arithmetic.
1. C truncates and MATLAB rounds on conversion from floating point to integer.
On conversion of a non-integer-valued floating point value to an integer data type, C truncates and MATLAB rounds (using MATLAB rounding, which is not the same as C rounding).
The following example C code:
int a = 3.7;
truncates the floating point value 3.7 to the (usually 32 bit) signed integer value 3.
The following example MATLAB code:
a = int32(3.7)
rounds the double constant 3.7 to the nearest int32 value 4.
We can use the INTWARNING function in MATLAB to turn on or off the warning state. When the "intwarning" is turned "on" via the command:
intwarning on
certain warning messages will be displayed when converting floating point values to integers.
When you perform the previous conversion of 3.7 to an int32 value, the following warning is generated:
Warning: Conversion rounded non-integer floating point value to nearest int32 value.
2. C wraps and MATLAB saturates on overflow
When converting to or performing arithmetic with unsigned integers according to the C standard, C wraps on overflow. The C standard does not specify whether to wrap or saturate on overflow when performing these operations with signed integers; however, in general, C usually wraps. MATLAB saturates under both these circumstances.
The C example code:
char a = 200;
converts the value 200 to the char (signed 8 bit integer) value -56, and:
unsigned char b = 300;
converts the value 300 to the unsigned char (unsigned 8 bit integer) value 44 after issuing the compile-time warning:
warning: large integer implicitly truncated to unsigned type.
Similarly, for C arithmetic:
char a = 100;
char b = a + a;
returns "b" with the (signed 8 bit) value -56, while:
unsigned char a = 200;
unsigned char b = a + a;
returns "b" with the (unsigned 8 bit) value 144.
The following MATLAB code:
a = int8(200)
produces the value 127, along with the warning message (when "intwarning" is "on")
 
Warning: Out of range value converted to intmin('int8') or intmax('int8').
Similarly, for MATLAB arithmetic:
int16(30000) + int16(30000)
produces intmax('int16') =32767, along with the warning message:
Warning: Out of range value or NaN computed in integer arithmetic.
3. C promotes and MATLAB demotes on interaction between integer data types and double.
In C, when an operation is performed on an integer data type with a double data type, the result will be the double data type. In MATLAB, when an operation is performed on an integer data type with a double data type, the result will be the integer data type.
In C, you can choose the data type of the result to be almost anything you want. However, the important point to remember when performing an operation is in which size and type of register the operation is performed. For mixed integer and double computations, the math is performed in the (at least double precision) floating point register, and a full scale double result can be generated, if desired. For MATLAB, double precision computations are also performed on each scalar element of the integer operand, but the final result is always cast back to the integer data type.
For example, the following C code:
double half = 5.0 / 3
returns the double value 1.66666 when you divide the double value 5.0 by the integer 3. This math was obviously performed in the floating point register, even if it was cast it to integer afterwards via
int one = 5.0 / 3; /* end value is 1 */
This returns an integer with truncated value 1.
The following MATLAB code:
5 / int32(3)
returns the int32 value 2. Because 5 is a double, the arithmetic was actually computed in double, and the intermediate result 1.6667 was rounded to int32(2) on return.
Note that in C, you can only operate on scalar operands. In MATLAB, the integer operand may be a matrix, but the double operand must be scalar.
No warning is issued from this operation.
Upon interaction between single and double data types, C will promote to a double, while MATLAB demotes to a single.
For example, the following C code divides a double by a single, and returns the size of the resulting data type:
float a = 5;
float b = 3;
printf("%i", sizeof(a/b));
We find the size of the result is 8 indicating a double data type is produced.
Within MATLAB, we can use the following commands:
class(double(5)/single(3))
which produces the result "single", indicating a single data type.
4. C and MATLAB compute chained expressions differently.
C computes a chained expression with consideration for all the operands in the expression, while MATLAB computes the chained expression in order of the parse tree, only considering the operands two at a time.
The following C example:
char a = 100, b = 2;
char c = (a * b) / 2.0;
returns c with value 100 because that floating point value 2.0 caused the whole chained expression to be evaluated in double, even though it was eventually cast into a char result.
The following MATLAB example:
int8(100) * int8(2) / 2
returns an int8 result with value 64 because the first multiplication overflowed to int8(127). The division with double 2 was actually performed in double, resulting in 63.5, which was then rounded on conversion back to int8.
This operation produces the warning message:
Warning: Out of range value or NaN computed in integer arithmetic.
5. C truncates on integer-integer division, while MATLAB performs double precision division with those integer values, and then rounds the double precision result back to the integer data type.
The C example:
int a = 2, b = 3;
double c = a / b;
returns c with the truncated value 0, because the division was performed as an integer operation, even though the result was cast to double after the division was performed.
The MATLAB example:
int32(2) / int32(3)
returns the rounded result int32(1) because the division was performed in double precision, and the result 0.66667 was then rounded to int32.
No warning is issued from this operation.

More Answers (0)

Categories

Find more on Numeric Types in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!