Matlab 将数字字符串转换为具有特定精度的浮点(无舍入错误)

Matlab 将数字字符串转换为具有特定精度的浮点(无舍入错误),matlab,floating-point,Matlab,Floating Point,我有一个单元格向量(比如说,大小为50x1,称为tokens),每个单元格都是一个结构,其属性为x,f1,f2,它们是表示数字的字符串。例如,tokens{15}给出: x: "-1.4343429" f1: "15.7947111" f2: "-5.8196158" 我试着把这些数字分成3个向量(每个向量也是50x1),它们的类型是float。所以我创建了3个向量: x = zeros(50,1,'single'); f1 = zeros(50,1,'single'); f2 = zeros

我有一个单元格向量(比如说,大小为
50x1
,称为
tokens
),每个单元格都是一个结构,其属性为
x
f1
f2
,它们是表示数字的字符串。例如,
tokens{15}
给出:

x: "-1.4343429"
f1: "15.7947111"
f2: "-5.8196158"
我试着把这些数字分成3个向量(每个向量也是
50x1
),它们的类型是
float
。所以我创建了3个向量:

x = zeros(50,1,'single');
f1 = zeros(50,1,'single');
f2 = zeros(50,1,'single');
这很好(为什么不呢?)。但是当我尝试填充这些向量时:(
L
是一个
for
循环索引)

我得到:

从字符串转换为单个字符串时发生以下错误: 无法从字符串转换为单个字符串

我能理解;隐式转换不适用于
单个
。如果
x
f1
f2
属于
50x1-double
类型,则它确实有效

我之所以使用浮点数,是因为我得到的数据来自一个C程序,该程序将一些浮点数写入一个文件,供matlab读取。如果我在C程序中尝试将值转换为双倍值,我会得到舍入误差

因此,(在我希望这是一个好问题之后,)我如何才能以正确的精度获得这些字符串中的数字?(所有字符串的小数位数相同:7)

MCVE:

filedata = fopen('fname1.txt','rt'); 
%fname1.txt is created by a C program. I am quite sure that the problem isn't there.
scanned = textscan(filedata,'%s','Delimiter','\n');
raw = scanned{1};
stringValues = strings(50,1);
for K=1:length(raw)
    stringValues(K)=raw{K};
end
clear K %purely for convenience

regex = 'x=(?<x>[\-\.0-9]*),f1=(?<f1>[\-\.0-9]*),f2=(?<f2>[\-\.0-9]*)';
tokens = regexp(stringValues,regex,'names');

x = zeros(50,1,'single');
f1 = zeros(50,1,'single');
f2 = zeros(50,1,'single');

for L=1:length(tokens)
    x(L)=tokens{L}.x;
    f1(L)=tokens{L}.f1;
    f2(L)=tokens{L}.f2;
end
filedata=fopen('fname1.txt','rt');
%fname1.txt由C程序创建。我很肯定问题不在那里。
扫描=文本扫描(文件数据,'%s','Delimiter','\n');
原始=扫描的{1};
stringValues=字符串(50,1);
对于K=1:长度(原始)
stringValues(K)=原始{K};
结束
清除K%纯粹是为了方便
正则表达式='x=(?[\-\.0-9]*),f1=(?[\-\.0-9]*),f2=(?[\-\.0-9]*);
tokens=regexp(stringValues,regex,'names');
x=零(50,1,'single');
f1=零(50,1,'single');
f2=零(50,1,'single');
对于L=1:长度(标记)
x(L)=令牌{L}.x;
f1(L)=令牌{L}.f1;
f2(L)=令牌{L}.f2;
结束

在分配到数组中之前,请使用function
str2double
(如果需要,可以将其强制转换为single)。字符串(字符数组)在用作数字之前必须明确转换为数字。

在分配到数组之前使用function
str2double
(如果需要,可以将其转换为single)。字符串(字符数组)在用作数字之前必须明确地转换为数字。

我很害怕发布这篇文章,但这里是这样的。我并没有完全理解这些,但请注意,在二进制基数和二元基数之间转换会导致额外的舍入错误。在两种表示法的精度之上。例如$0.\dot{3}$≈ 0.333333≈ 0.010101010≈ 033203125@ctrl-alt delor不确定我是否明白这有什么关系。可能不是“我没有完全理解,但是…”我很害怕发布这篇文章,但这里是这样的。我没有完全理解,但请注意,在二进制基数和二进制基数之间转换会导致额外的舍入错误。在两种表示法的精度之上。例如$0.\dot{3}$≈ 0.333333≈ 0.010101010≈ 033203125@ctrl-alt delor不确定我是否理解这一点。可能不是“我没有遵循所有这些,但是…”我不确定我是否理解这一点。你能给出一个例子或一些解释吗?
x(L)=single(str2double(tokens{L}.x))
@Bentoy13正确,但请注意,
单精度(str2double(x))
需要进行双舍入,并且可以将最接近的单精度浮点值减至x。。。遗憾的是,Matlab没有提供一个单独的str2…。@aka.nice完全同意。我不明白有
str2num
str2double
以及没有
str2num(类)
的意义。我不知道如何避免潜在的舍入。我不知道这是怎么回事。你能给出一个例子或一些解释吗?
x(L)=single(str2double(tokens{L}.x))
@Bentoy13正确,但请注意,
单精度(str2double(x))
需要进行双舍入,并且可以将最接近的单精度浮点值减至x。。。遗憾的是,Matlab没有提供一个单独的str2…。@aka.nice完全同意。我不明白有
str2num
str2double
以及没有
str2num(类)
的意义。我不知道如何避免可能的舍入。
filedata = fopen('fname1.txt','rt'); 
%fname1.txt is created by a C program. I am quite sure that the problem isn't there.
scanned = textscan(filedata,'%s','Delimiter','\n');
raw = scanned{1};
stringValues = strings(50,1);
for K=1:length(raw)
    stringValues(K)=raw{K};
end
clear K %purely for convenience

regex = 'x=(?<x>[\-\.0-9]*),f1=(?<f1>[\-\.0-9]*),f2=(?<f2>[\-\.0-9]*)';
tokens = regexp(stringValues,regex,'names');

x = zeros(50,1,'single');
f1 = zeros(50,1,'single');
f2 = zeros(50,1,'single');

for L=1:length(tokens)
    x(L)=tokens{L}.x;
    f1(L)=tokens{L}.f1;
    f2(L)=tokens{L}.f2;
end