简体   繁体   English

在Matlab中使用TextScan错误的浮点精度

[英]Wrong float precision using textscan in Matlab

I have a devised a function in matlab that allows me (or so I thought) to extract data from a textfile that looks like this (at least the beginning) 我在matlab中设计了一个函数,该函数允许我(或我认为)从看起来像这样的文本文件中提取数据(至少是开始时)

G1 50
G2 50
M-0.35 0
M-0.05 0.013
M3.3 0.1
M9.75 0.236
M17.15 0.425
M25.85 0.666
M35.35 0.958

The idea is to match the letter I have with its position with a vector (because only the values next to M are really interesting to me), and get the two other numbers in a vector. 这个想法是将我所拥有的字母与它的位置与一个向量相匹配(因为只有M旁边的值对我来说真的很有趣),并在向量中得到另外两个数字。 The end of the treatment works well, but the values I get by the end of my code are sometimes far from the real ones. 处理的末尾效果很好,但是我在代码末尾得到的值有时与实际值相差甚远。

For instance, instead of [0 0.013 0.1 0.236 0.425 0.666 0.958] I get [0 0.013 0.1010 0.237 0.426 0.666 0.959]. 例如,代替[0 0.013 0.1 0.236 0.425 0.666 0.958],我得到[0 0.013 0.1010 0.237 0.426 0.666 0.959]。 This is not such an issue, the problem is much worse for the first column : instead of a maximum at 119, it doesn't reach 90. I had a code that worked properly with integers, but now I'm using floats it fails everytime. 这不是问题,第一列的问题要严重得多:不是最大为119,而是没有达到90。我有一个可以正确使用整数的代码,但是现在我使用浮点数失败每次。

I will try and display only the interesting parts of the code : 我将尝试仅显示代码中有趣的部分:

nom_essai='test.txt'     
fid1 = fopen(nom_essai, 'rt');
tableau = textscan(fid1, '%s %.5f ', 'HeaderLines', 1, 'CollectOutput', true); %There are a few lines that I skip because they give the parameters, I get them with another line of the code
colonne_force=tableau{1}; %on recupere la premiere colonne
colonne_deplacement=tableau{2}; %on recupere la seconde colonne


indice=2*found_G+found_F+3*found_R; %this is the result of the treatment on colonne_force to match an index with the letter, which helps me keep the period next to G and the 2 values next to M.

force=linspace(0,0,length(n_indices)); %initialisation
    deplacement=linspace(0,0,length(n_indices)); %initialisation
    temps=linspace(0,0,length(n_indices)); %initialisation


    for k=1:length(colonne_force) %%%%k is for the length of my vectors, while j is for the length of the columns
        if indice(k)==2 %un G est trouve => temps d'echantillonnage
            T=colonne_deplacement(k); %to keep the period next to G
            end
        elseif indice(k)==1 %an F is found : skip it
        elseif indice(k)==3 %an R is found : skip it
        else %an M is found : I need to get the values on these lines
            j=j+1;
            deplacement(j)=colonne_deplacement(k); %I keep the value on the second column
            M=strsplit(colonne_force{k},'M'); %I get the string 'MXXX'
            force(j)=str2double(M{2}); %I recover this string without the M, and convert the number to double                 
        end
    end

The kind of precision I would like to have is to keep values like [M108.55 23.759] with up to 3 digits. 我想要的精度是保持[M108.55 23.759]之类的值最多3个数字。

Thank you in advance, feel free to ask for any information if I failed to give only the part of the code that contains the problem. 在此先感谢您,如果我未能仅给出包含该问题的代码部分,请随时询问任何信息。

Modifying a bit your code as: 将您的代码修改为:

nom_essai='test.txt';     
fid1 = fopen(nom_essai, 'rt');
tableau = textscan(fid1, '%s %f ', 'HeaderLines', 1, 'CollectOutput', true); % Change to %f not to miss significative figures
colonne_force = tableau{1}; %on recupere la premiere colonne
colonne_deplacement=tableau{2}; %on recupere la seconde colonne

% Check if has M

hasM = cellfun(@(x) any(x == 'M'), colonne_force);

column2 = colonne_deplacement(hasM);

column1 = colonne_force(hasM);
column1 = cellfun(@(x) str2double(x(2:end)), column1); % delete M and convert to double

The precision is retained: 精度保持不变:

向量的值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM