提问人:Enlico 提问时间:9/28/2021 最后编辑:Enlico 更新时间:9/29/2021 访问量:211
MATLAB 是否提供从双精度到字符串的无损转换函数?
Does MATLAB provide a lossless coversion function from double to string?
问:
tl;博士
我只是在寻找两个函数,从 to 和 from to ,这样对于任何双精度(标量和实数)。f
double
string
g
string
double
g(f(d)) == d
d
double
原始问题
如何以可逆的方式将 a 转换为 a 或数组?我的意思是,以这样一种方式,之后我可以将该/数组转换回检索原始结果。double
string
char
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 个数字的字符串,这些数字对应于 的内部表示中的字节。函数 typecast
将字节提取为数值向量,num2str
转换为数字用空格分隔的 char 向量。x
功能:从字符向量到双实值标量g
str
y
y = typecast(uint8(str2double(strsplit(str))), 'double');
char 向量使用 strsplit
在空格处拆分。结果是 char 向量的元胞数组,然后 str2double
将每个向量解释为一个数字,从而产生一个数值向量。这些数字被强制转换为 uint8
,然后将它们解释为双实值标量的内部表示。typecast
请注意,它比更简单的 ,因为 str2num
在内部调用 eval
,这被认为是邪恶的不良做法。str2double(strsplit(str))
str2num(str)
例
>> 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
这里有两个更简单的解决方案,可以将单个双精度值转换为字符串并返回而不会丢失。
我希望字符串是数字的人类可读表示形式
使用 num2str
获取字符串形式的 17 位十进制数字,使用 str2double
转换回来:
>> s = mat2str(x,17)
s =
'2.2204460492503131e-16'
>> y = str2double(s);
>> y==x
ans =
logical
1
请注意,17 位数字始终足以表示任何 IEEE 双精度浮点数。
我想要一个更紧凑的数字字符串表示形式
使用 matlab.net.base64encode
对数字的 8 个字节进行编码。不幸的是,您只能对字符串和整数数组进行编码,因此我们将 cast 键入到某个整数数组(我们在这里使用,但也有效)。我们反转该过程以返回相同的双精度值: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 个字节)。
评论
mat2str
应该完全按照你的意愿去做,它甚至可以保留数值类型。不需要指定精度,也不应该指定精度。A = eval(
chr) 将原始矩阵中的值重现为chr
中指定的精度,但也不为零。str2double(mat2str(eps)) - eps
str2double
eval(mat2str(eps)) - eps
mat2str
x
str = ['typecast(uint8(' mat2str(typecast(x, 'uint8')) '),''' class(x) ''')']
eval(str)-x
x
x