将双精度型保存到字符串时,会损失一些精度。即使您使用大量数字,转换也可能不可逆,即,如果将双x
转换为字符串sx
,然后再转换回数字,您将得到一个数字x'
可能不等于x
。例如,当检查一组测试中的差异时,这可能会引起一些问题。一种可能性是使用二进制形式(例如本机二进制形式或HDF5),但我想将数字存储在文本文件中,因此我需要转换为字符串。我有一个可行的解决方案,但请问是否有针对此或更佳解决方案的标准。
在C / C ++中,您可以将双精度转换为某个整数类型,例如char*
,然后使用printf("%02x",c[j])
将每个字节转换为长度为2的六进制。然后,例如PI将被转换为长度为16的字符串:54442d18400921fb
。这样做的问题是,如果您阅读十六进制,您将不会知道它是哪个数字。因此,我对诸如pi-> 3.14{54442d18400921fb}
之类的一些混合感兴趣。第一部分是数字的(可能是低精度)十进制表示形式(通常我会使用"%g"
输出转换),大括号中的字符串是无损十六进制表示形式。
编辑:我将代码作为请求者传递
答案 0 :(得分:1)
按照帖子中已经提出的想法,我写了 以下功能似乎有效。
function s = dbl2str(d);
z = typecast(d,"uint32");
s = sprintf("%.3g{%08x%08x}\n",d,z);
endfunction
function d = str2dbl(s);
k1 = index(s,"{");
k2 = index(s,"}");
## Check that there is a balanced {} or not at all
assert((k1==0) == (k2==0));
if k1>0; assert(k2>k1); endif
if (k1==0);
## If there is not {hexa} part convert with loss
d = str2double(s);
else
## Convert lossless
ss = substr(s,k1+1,k2-k1-1);
z = uint32(sscanf(ss,"%8x",2));
d = typecast(z,"double");
endif
endfunction
那我有
>> spi=dbl2str(pi)
spi = 3.14{54442d18400921fb}
>> pi2 = str2dbl(spi)
pi2 = 3.1416
>> pi2-pi
ans = 0
>> snan = dbl2str(NaN)
snan = NaN{000000007ff80000}
>> nan1 = str2dbl(snan)
nan1 = NaN
进一步的改进是使用其他类型的环境 实例Base64(由@CrisLuengo在评论中建议) 将二进制部分的长度从16个字节减少到11个字节。