Round, With Tie breaker,一个原型

在2月和3月,我发表了三篇关于MATLAB的增强请求的博客文章函数,包括将平局四舍五入为偶数的能力。圆的一个第二轮而且圆三.从那时起,我的同事(也是学术界的曾曾曾孙后代)海科·韦切特(Heiko Weichelt)组织的MathWorks团队一直在考虑这个请求。我们最近进行了一次虚拟设计评审。这篇文章描述了一个原型,包含了在评审中讨论过的功能。

内容

传统上,帮助轮只有一条线。

ROUND(X)将X的每个元素四舍五入到最接近的整数。

几年前,添加了两个可选参数。

ROUND(X, N),对于正整数N,四舍五入到小数点右边的N位。如果N为零,则X四舍五入为最接近的整数。如果N小于零,X取小数点左四舍五入。N必须是标量整数。
ROUND(X, N, 'significant')将每个元素舍入到它的N位最高有效位数,从数字的最高有效位数或左侧开始计数。N必须是正整数标量。

地板和天花板

的函数地板上而且装天花板在任何舍入的讨论中都有重要的作用。每一个实数,x,它不是整数,位于两个整数之间,

地板(x) < x <天花板(x) =地板(x) + 1

如果x是整数吗

地板(x) = x =天花板(x)

这个函数地板(x)定义了“舍入x趋近于负无穷"和函数装天花板(x)是“舍入x朝向正无穷”。

这个函数修复(x)的整数部分x”,是

Fix (x) = floor(x)如果x >= 0, = ceil(x)如果x < 0。

的小数部分x”是

Frac (x) = x - fix(x)。

两个例子

X = 9.64 X = -9.64 floor(X) = 9 floor(X) = -10 ceil(X) = 10 ceil(X) = -9 fix(X) = 9 fix(X) = -9 frac(X) = 0.64 frac(X) = -0.64

关系

传统的代码轮(x)是一行。

圆(x) =符号(x).*底(abs(x) + 0.5)

这意味着

如果裂缝(x) < 0.5,则圆(x) =底部(x) =上部(x),如果裂缝(x) > 0.5

这明确地定义了轮(x)几乎所有人x.唯一含糊不清的情况是舍入的关系.它们发生在小数部分x正好是1/2,或者十进制的0.5。领带相对较少。传统上,MATLAB是四舍五入的。

当没有指定缩放比例时,ties是两个连续整数之间的数字,

普= -3.5,-2.5,-1.5,-0.5,0.5,1.5,2.5,3.5,……

“圆与零的距离”规则产生了

Round (half) = -4, -3, -2, -1, 1,2,3,4,…

最近,人们对这种行为的替代方法产生了一些兴趣。一种选择是“圆系到最近的偶数”。对于中间数,这将是

Halfs_even = -4, -2, -2, 0,0,2,2,4,…

最近的小数

这里有四个四舍五入到最接近的十进制值的例子。

格式格式紧凑的
  • 用整数表示城际里程距离。从我的家庭办公室到MathWorks总部的距离是406.3英里。这是多少英里?
英里=整(406.3)
英里= 406
  • 病人的体温是98.64华氏度。用十分之一度来表示。
温度=圆(98.64,1)
温度= 98.6000
  • 以百分之一表示货币价值。计算的利息是13.8327欧元。用百分之一欧元来表示。
分=整数(13.8327,2)
美分= 13.8300
  • 据报道,2019年塔拉哈西的人口为19.45万。这对最接近的一千人来说算什么?
pop = Round(194500,-3)
流行= 195000

这些例子中只有一个涉及到领带。按照整数到偶数的规则,塔拉哈西的人口将被列为19.4万人,而不是19.5万人。

IEEE 754

函数与IEEE 754浮点算法的整数到偶数设置不相同。的用MATLAB软件完成功能;它的输入是double(或single),输出是flint(值为整数的浮点数)。IEEE 754设置是在硬件中完成的,它的输入是扩展精度或带有保护位的寄存器,它的输出是很少使用燧石的双精度。

名称-值对

一些审查人员更喜欢名称-值对。名称-值对一直是MATLAB语法的一部分,最近的改进涉及到使用等号来指定它们。例如

情节(x, y,‘ko’,‘markersize’,10)

现在可以写成

情节(x, y,标志=“o”,颜色=黑色,markersize = 10)

名称-值对的左边部分是paramName右边可能的分量是paramValues

起初,我并不热衷于使用名称-值对进行捆绑制动.但在完成这个原型和博客文章之后,我现在赞成了。的paramName可能是

roundTies

有六种可能paramValues

从0到0到偶数到add到正无穷到负无穷

例如

x = (0.1:0.2:0.9)' r_from = Round(x,roundTies=“awayFromZero”) r_even = Round(x,roundTies=“低”
X = 0.1000 0.3000 0.5000 0.7000 0.9000 r_from = 00 1 1 1 r_even = 000 1 1

不是一个数字

这是我在写这篇文章时想到的。第七种处理领带的方法怎么样?

r_nan = Round(x,roundTies=“toNaN”
r_nan = 0 0 NaN 1 1

帮助

接下来的五个部分是原型的代码。文件名为Round.m大写字母R所以我们也可以访问函数。代码在这里:Round.m

代码= split(string(fileread(“Round.m”)),“% _”);

帮助文本很简洁。

(1) disp(代码)
function x =舍入(varargin) %向最近的十进制或整数舍入。% %四舍五入(x)将x的每个元素四舍五入到最接近的整数。% %四舍五入(x, n)四舍五入到小数点后n位。%四舍五入(x, n, digits="significant")四舍五入到n位有效数字。% round(x,n, digits="decimal ")与round(x,n)相同。% % round(x,…,roundTies="awayFromZero") % round(x,..., roundTies="towardsZero") % round(x,..., roundTies="toOdd") % round(x,..., roundTies="toEven") % round(x,..., roundTies="towardsPlusInfinity") % round(x,..., roundTies="towardsMinusInfinity") % % Ties are rare. round(x,n) is a tie only when 10^n*x is within % roundoff error of a point halfway between two consecutive integers.

例子

帮助文本继续提供了一些示例。

(2) disp(代码)
x = 123456.789% % % % %例子一轮轮(x, 3) (x) 123457% 123000%圆(x, 2) 123456.79% % x = 1.125% %一轮轮(x, 1) (x) 1.000% 1.100%轮轮(x, 2) 1.130% (x 2 roundTies =“低”)1.120%轮(x 2 roundTies =“toOdd”)1.130%的圆轮(x, 3) 1.125% (x 3“重大”)1.130% % x = 1.115% xlo = 1115/1000 - eps / 25% xhi = 1115/1000 + 24 * eps / 25% %一轮轮(x, 2) 1.120% (xlo 2 roundTies =“toOdd”)1.110%轮(xhi 2 roundTies =“低”)1.120

主要

这是.数值敏感部分是定义的确切的选择<< =在确定t领带。

(3) disp(代码)
% main program [x,n,sig,tie] = parse(varargin{:});X0 = x;S =符号(x);X = abs(X);如果sig n = n - ceil(log10(x));Else n = n - 0 (size(x));End x = scale(x,n);Z = x;F = z - floor(z);M = (f < 0.5); x(m) = floor(z(m)); m = (f >= 0.5); x(m) = ceil(z(m)); exact = (x0 == single(x0)); if exact t = (f == 0.5); % ties else t = abs(f - 0.5) <= eps(z); % ties end x(t) = ceil(z(t)); switch tie case 'even' m = (mod(x(t),2) == 1); case 'odd' m = (mod(x(t),2) == 0); case 'plus' m = (s(t) < 0); case 'minus' m = (s(t) > 0); case 'zero' m = 1; case 'nan' m = NaN; otherwise m = 0; end x(t) = x(t) - m; x = s.*scale(x,-n);

解析

这个解析器以非常简单的方式处理名称-值对。一个更严肃的解析器会更有鉴别力。

(4) disp(代码)
函数[x,n,sig,tie] =解析(varargin) x = varargin{1};N = 0;Sig = false;Tie = 'from';对于k = 2:nargin vk = varargin{k};如果isnumeric(vk) n = vk;Elseif vk == "significant" sig = true;Elseif vk == "decimals" ||…vk == "roundTies" ||…Vk == "digits" %忽略else tie = char(Vk); caps = find(double(tie) < double('a')); if length(caps) > 1 && caps(2) > caps(1)+2 tie = lower(tie(caps(1):caps(2)-1)); elseif length(caps) > 0 && length(tie(caps:end)) <= 5 tie = lower(tie(caps(1):end)); else error(vk + " not recognized.") end end end end

规模

这个缩放函数总是乘或除10的正整数次幂,这是精确的N <= 16

(5) disp(代码)
函数x = scale(x,n) k = (n > 0);X (k) = X (k).*10.^n(k);K = (n < 0);X (k) = X (k)./10.^(-n(k));结束

图形

下面是以前帖子中的图表,现在标记为paramValues

图形

软件

原型代码可以在这里找到:Round.m




发布与MATLAB®R2021b

|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。