Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matlab single to double conversion error [duplicate]

Does someone know why casting double() on a single precision floating point number in Matlab (R2016a) changes the last digits? Here is an example:

format 'long'
x=3.2530601; %arbitrary single precision number
x_s=single(x);
x_d=double(x_s);

If I look at the classes and values of the variables, I can see the following: x and x_d are doubles, x_s is single as expected. The values are:

x=3.253060100000000
x_s=3.2530601
x_d=3.253060102462769

Since the number 3.2530601 can be represented as a double or single precision floating point number, I don't understant why x and x_d are not the same. They are further away than x+eps(x). I thought maybe Matlab tries to work out the double precision x_d by rational fraction approximation, but calling rat(x,16) does not give the same result as x_d. I'm clueless. Does anyone know what is happening here?

like image 812
David Avatar asked Feb 21 '18 17:02

David


1 Answers

There are two closely-related questions (In MATLAB, are variables REALLY double-precision by default? and Why is 24.0000 not equal to 24.0000 in MATLAB?), that you should be aware of, but this isn't quite covered fully by either of them...

When you calculate the decimal equivalent for a given significand and exponent of a floating-point value, you can calculate it out to as many decimal places as you want, but any places beyond the floating-point relative accuracy are ultimately of no real value and are typically not even displayed. However, they seem to come into play here when converting a lower-precision number to a higher-precision number.

Let's look at your value for x_s, both as it is displayed normally (only showing significant digits) and how vpa would display it (with an arbitrary number of digits):

>> x_s = single(3.2530601)  % Create a single-precision number

x_s =

  single

   3.2530601

>> eps(x_s)  % Floating-point relative accuracy

ans =

  single

   2.3841858e-07

>> vpa(x_s, 16)  % Show 16 digits of precision, way more than the relative accuracy

ans =

3.253060102462769

>> x_d = double(x_s)  % Convert to double-precision

x_d =

   3.253060102462769

Look at that! The digits from vpa match the digits gotten when converting to double-precision. It would appear that, when converting from a single to a double, MATLAB calculates the decimal equivalent of the lower-precision value out to the number of digits for the higher-precision value, and uses that to initialize it.

like image 97
gnovice Avatar answered Sep 30 '22 02:09

gnovice