Search code examples
stringmatlabtype-conversionprecisionchararray

Does MATLAB provide a lossless coversion function from double to string?


tl;dr

I'm just looking for two functions, f from double to string and g from string to double, such that g(f(d)) == d for any double d (scalar and real double).

Original question

How do I convert a double to a string or char array in a reversible way? I mean, in such a way that afterward I can convert that string/char array back to double retrieving the original result.

I've found formattedDisplayText, and in some situations it works:

>> x = eps

x =

     2.220446049250313e-16

>> double(formattedDisplayText(x, 'NumericFormat', 'long')) - x

ans =

     0

But in others it doesn't

x = rand(1)

x =

   0.546881519204984

>> double(formattedDisplayText(x, 'NumericFormat', 'long')) - x

ans =

     1.110223024625157e-16

As regards this and other tools like num2str, mat2str, at the end they all require me to decide a precision, whereas I would like to express the idea of "use whatever precision is needed for you (MATLAB) to be able to read back your own number".


Solution

  • Here are two simpler solutions to convert a single double value to a string and back without loss.

    I want the string to be a human-readable representation of the number

    Use num2str to obtain 17 decimal digits in string form, and str2double to convert back:

    >> s = mat2str(x,17) 
    s =
        '2.2204460492503131e-16'
    >> y = str2double(s);
    >> y==x
    ans =
      logical
       1
    

    Note that 17 digits are always enough to represent any IEEE double-precision floating-point number.

    I want a more compact string representation of the number

    Use matlab.net.base64encode to encode the 8 bytes of the number. Unfortunately you can only encode strings and integer arrays, so we type cast to some integer array (we use uint8 here, but uint64 would work too). We reverse the process to get the same double value back:

    >> s = matlab.net.base64encode(typecast(x,'uint8'))
    s =
        'AAAAAAAAsDw='
    >> y = typecast(matlab.net.base64decode(s),'double');
    >> x==y
    ans =
      logical
       1
    

    Base64 encodes every 3 bytes in 4 characters, this is the most compact representation you can easily create. A more complex algorithm could likely convert into a smaller UTF-8-encoded string (which uses more than 6 bytes per displayable character).