在工程学科中,对于数据精度的要求越来越高,因此对于数据的处理也需要更加精确。四舍五入是一种常用的数值处理方式。在 Matlab 中,实现精确的四舍五入功能并不难,接下来我们将介绍详细的实现方法。
一、Matlab 中的 round 函数
Matlab 中提供了 round 函数,这个函数可以实现四舍五入功能,如下:
round(X) % 四舍五入至最近的整数
round(X, N) % 四舍五入至 N 位小数
其中 X 是需要四舍五入的数,N 是需要保留的小数位数。round 函数是非常常用的数值处理函数,可以实现简单的四舍五入功能。但是当需要精确处理风险时, round 函数就显得力不从心了。
二、实现精确的四舍五入功能
由于 Matlab 中 round 函数精度不够,因此需要采用其他的数学方法来实现精确的四舍五入功能。
1.采用 sprintf 函数实现精确的四舍五入
sprintf 函数可以实现字符串的格式化输出,通过其精度控制可以实现数值的四舍五入。sprintf 函数的语法形式如下:
S = sprintf(fmt, A)
其中 fmt 是格式化控制字符串(包含了格式说明),A 是输入的数据。使用 sprintf 函数实现精确的四舍五入的代码如下:
function r = myround(x, n)
fmt = sprintf('%%.%df', n);
r = sscanf(sprintf(fmt, x), '%f', 1);
end
代码非常简单,首先将 fmt 字符串格式化成需要保留小数位的格式,然后再使用 sscanf 函数将字符串转换为浮点数数据。对于 0.5 与 -0.5进行四舍五入是存在问题的,以上函数给出针对此类问题的完整解决方案如下:
function r = myround(x, n)
if x > 0
r = (floor(x .* 10 .^ n + 0.5)) ./ 10.^n;
else
r = - (floor(-x .* 10.^n + 0.5)) ./ 10.^n;
end
end
2.自行编写算法实现
除了采用 sprintf 函数可以实现精确的四舍五入,我们还可以自行编写算法实现,具体实现步骤如下:
(1)将需要保留的位数转换成整数,如四舍五入 3 位小数就转换成转换成整数 10^3。
(2)将要舍入的数乘上上述得到的整数,得到一个整数数值。
(3)判断这个数值与原始的数值的大小,并以此来进行四舍五入操作。如若要舍入的数大于原数(此时小数点后第 n+1 位为1)的四舍五入规律就变成了,例如: 5.13 要保留 1 位小数小数时,因为第二位数字为 1,所以要舍入到 1 位小数,那么就是第一位数字 3 加 1 等于 4,所以四舍五入后等于 5.1。
(4)将舍入得到的整数再除以整数出现的次数。
具体实现代码如下:
function y = my_round(x, n)
k = 10.^n;
if x>=0
y = floor(x*k+0.5)./k;
else
y = -floor((-x)*k+0.5)./k;
end
end
三、实现方法比较
下面我们通过对比不同方法所得到的结果和精度等级的测试,来比较三种实现方法。
1. round 函数示例:
a = [1.5, -1.5, 3.14159, -3.14159];
b = [1.4, -1.4, 3.14159, -3.14159];
c = [1.6, -1.6, 3.14159, -3.14159];
% 默认保留整数
round(a) % [2 -2 3 -3]
round(b) % [1 -1 3 -3]
round(c) % [2 -2 3 -3]
% 保留两位小数
round(a, 2) % [1.50 -1.50 3.14 -3.14]
round(b, 2) % [1.40 -1.40 3.14 -3.14]
round(c, 2) % [1.60 -1.60 3.14 -3.14]
2. sprintf 函数示例:
a = [1.5, -1.5, 3.14159, -3.14159];
b = [1.4, -1.4, 3.14159, -3.14159];
c = [1.6, -1.6, 3.14159, -3.14159];
% 默认保留整数
sprintf('%.0f', a) % [2 -2 3 -3]
sprintf('%.0f', b) % [1 -1 3 -3]
sprintf('%.0f', c) % [2 -2 3 -3]
% 保留两位小数
sprintf('%.2f', a) % [1.50 -1.50 3.14 -3.14]
sprintf('%.2f', b) % [1.40 -1.40 3.14 -3.14]
sprintf('%.2f', c) % [1.60 -1.60 3.14 -3.14]
3. 自行编写算法示例:
a = [1.5, -1.5, 3.14159, -3.14159];
b = [1.4, -1.4, 3.14159, -3.14159];
c = [1.6, -1.6, 3.14159, -3.14159];
% 默认保留整数
my_round(a, 0) % [2 -2 3 -3]
my_round(b, 0) % [1 -1 3 -3]
my_round(c, 0) % [2 -2 3 -3]
% 保留两位小数
my_round(a, 2) % [1.50 -1.50 3.14 -3.14]
my_round(b, 2) % [1.40 -1.40 3.14 -3.14]
my_round(c, 2) % [1.60 -1.60 3.14 -3.14]
通过上面的测试可以发现, round 函数在处理负数时结果是不准确的, sprintf 函数可以精确处理,但是代码量相对较大。在处理精度较高的数据时,通过自行编写算法实现四舍五入可以达到最优的效果。
四、总结
在 Matlab 中实现精确的四舍五入功能需要采用一些特殊的算法来实现。在上面的实现方法对比中我们可以看到采用 sprintf 函数实现精确的四舍五入虽然代码量较大,但是结果精度非常高,在处理需要精准度更高的数据时可以采用该方法。当然如果想要实现更高精度地四舍五入,也可以自己手写算法来实现。