控制分割精度
Controlling division precision
考虑以下简单的除法:
A=8.868;
A/0.1
ans =
88.679999999999993
由于浮点精度,这会导致一个小错误。有什么办法可以防止这种情况发生吗?基本上我所做的就是将逗号移动一个位置,同时不接近 MATLAB 中允许的最大位数。
我想获得如下结果:
A/0.1
ans =
88.68
尾随零无关紧要,只要它们只是零,并且不包含第 14 位左右的数字。
有趣的是,当四舍五入到 N
位时也会出现此问题:
R = (randi([8659 49847],[1e3 1]))/1e3;
xmin = min(R);
el = 0.1;
step = 1/el;
tmp1=xmin/el;
tmp2=round(tmp1);
tmp3=round(tmp2*el,3);
tmp3 =
8.699999999999999
使用符号数学,您可以获得精确的结果:
x=sym('8.868')/sym('.1')
您可以随时使用 fixed point arithmetics where the slope is a multiple of 10. You won't have any inaccuracies when you multiply/divide by ten. In Matlab, you can use Fixed Point Toolbox
编辑: 根据您的评论 - 看起来您可以将斜率设置为 0.05。
您可以将数字表示为整数的分数。只要不转为浮点数,就不会丢失精度:
A = 8.868;
div = 0.1;
[N1,D1] = rat(A);
[N2,D2] = rat(div);
% divide A by div:
N = N1 * D2;
D = N2 * D1;
当然,您的数字一开始可能并不精确,如其他 answers/comments 中所述。分数转换也可以引入近似值,但这取决于你处理的数字和 rat
.
的 tol
参数
发布此答案只是为了我的案例的完整性。
我使用 unique
的第三个输出在我的案例中稍微规避了这个问题:
el = 0.25;
A = (randi([7364 84635],[1e4 1]))/1e3;
B = A/el;
C = round(B);
D = C*el;
[tmp1,tmp2,tmp3] = unique(D);
E = tmp1(tmp3,:);
all(E==D)
ans =
1
哪个正确地进行了装箱。因此,即使中心点可能不精确到无限精度,它们至少在 10 位数字以内,这超过了我原始数据的 3 位数字精度。
考虑以下简单的除法:
A=8.868;
A/0.1
ans =
88.679999999999993
由于浮点精度,这会导致一个小错误。有什么办法可以防止这种情况发生吗?基本上我所做的就是将逗号移动一个位置,同时不接近 MATLAB 中允许的最大位数。
我想获得如下结果:
A/0.1
ans =
88.68
尾随零无关紧要,只要它们只是零,并且不包含第 14 位左右的数字。
有趣的是,当四舍五入到 N
位时也会出现此问题:
R = (randi([8659 49847],[1e3 1]))/1e3;
xmin = min(R);
el = 0.1;
step = 1/el;
tmp1=xmin/el;
tmp2=round(tmp1);
tmp3=round(tmp2*el,3);
tmp3 =
8.699999999999999
使用符号数学,您可以获得精确的结果:
x=sym('8.868')/sym('.1')
您可以随时使用 fixed point arithmetics where the slope is a multiple of 10. You won't have any inaccuracies when you multiply/divide by ten. In Matlab, you can use Fixed Point Toolbox
编辑: 根据您的评论 - 看起来您可以将斜率设置为 0.05。
您可以将数字表示为整数的分数。只要不转为浮点数,就不会丢失精度:
A = 8.868;
div = 0.1;
[N1,D1] = rat(A);
[N2,D2] = rat(div);
% divide A by div:
N = N1 * D2;
D = N2 * D1;
当然,您的数字一开始可能并不精确,如其他 answers/comments 中所述。分数转换也可以引入近似值,但这取决于你处理的数字和 rat
.
tol
参数
发布此答案只是为了我的案例的完整性。
我使用 unique
的第三个输出在我的案例中稍微规避了这个问题:
el = 0.25;
A = (randi([7364 84635],[1e4 1]))/1e3;
B = A/el;
C = round(B);
D = C*el;
[tmp1,tmp2,tmp3] = unique(D);
E = tmp1(tmp3,:);
all(E==D)
ans =
1
哪个正确地进行了装箱。因此,即使中心点可能不精确到无限精度,它们至少在 10 位数字以内,这超过了我原始数据的 3 位数字精度。