MATLAB 是否提供从 double 到 string 的无损转换函数?

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

tl;博士

我只是在寻找两个函数,fdoublestringgstringdouble,这样 g(f(d)) == d 对于任何双 d(标量和实数 double)。

原问题

如何以可逆方式将 double 转换为 stringchar 数组?我的意思是,之后我可以将 string/char 数组转换回 double 以检索原始结果。

我发现 formattedDisplayText,在某些情况下它有效:

>> x = eps

x =

     2.220446049250313e-16

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

ans =

     0

但在其他情况下则不然

x = rand(1)

x =

   0.546881519204984

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

ans =

     1.110223024625157e-16

关于这个和其他工具,比如 num2str, mat2str,最后他们都要求我决定一个精度,而我想表达“使用你需要的任何精度(MATLAB)”的想法能够读回你自己的号码。

函数f:从双实数值标量x到字符向量str

str = num2str(typecast(x, 'uint8'));

str 被构建为一个包含 8 个数字的字符串,对应于 x 的内部表示中的字节。函数 typecast extracts the bytes as a numerical vector, and num2str 转换为数字以空格分隔的字符向量。

函数g:从字符向量str到双精度实数值标量y

y = typecast(uint8(str2double(strsplit(str))), 'double');

char 向量使用 strsplit. The result is a cell array of char vectors, each of which is then interpreted as a number by str2double, which produces a numerical vector. The numbers are cast to uint8 在空格处拆分,然后 typecast 将它们解释为双实数值标量的内部表示。

请注意 str2double(strsplit(str)) 优于更简单的 str2num(str),因为 str2num internally calls eval, which is considered evil bad practice.

例子

>> format long
>> x = sqrt(pi)
x =
   1.772453850905516
>> str = num2str(typecast(x, 'uint8'))
str =
    '106  239  180  145  248   91  252   63'
>> y = typecast(uint8(str2double(strsplit(str))), 'double')
y =
   1.772453850905516
>> x==y
ans =
  logical
   1

这里有两个更简单的解决方案,可以将单个 double 值无损地转换为字符串并返回。

我希望字符串是数字的人类可读表示形式

使用num2str to obtain 17 decimal digits in string form, and str2double转换回来:

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

请注意,17 位数字始终足以表示任何 IEEE double-precision floating-point number

我想要数字的更紧凑的字符串表示形式

使用matlab.net.base64encode对数字的8个字节进行编码。不幸的是,您只能对字符串和整数数组进行编码,因此我们将类型转换为某个整数数组(我们在这里使用 uint8,但 uint64 也可以)。我们反转这个过程以获得相同的双精度值:

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

Base64 对 4 个字符中的每 3 个字节进行编码,这是您可以轻松创建的最紧凑的表示形式。更复杂的算法可能会转换为更小的 UTF-8 编码字符串(每个可显示字符使用超过 6 个字节)。