克利夫角:克利夫Moler的数学和计算

科学计算,数学和更多

第二轮,第三轮

我最近出版的Round, With Ties to Even然后是第二轮.然后,在一封电子邮件中,安迪·巴特利特指出,我的新对于一些较大的值,函数会失败x之间的flintmax / 2flintmax

内容

flintmax / 2

的数量f = flintmax / 2等于2 ^ 52,这是1 /每股收益.的帮助条目格式的银行说这是美元和美分的固定格式。这是真的,但我也喜欢用它显示大燧石。

格式银行f = flintmax / 2
f = 4503599627370496.00

区间内的数字[f flintmax]最大燧石。它们都是整数。它们之间的距离是1。

每股收益(f)
ans = 1.00

大于的所有浮点数flintmax是整数,但它们之间的间隔大于1,因此不能用于整数算术。

舍入

所有版本背后的想法是这样的。假设abs (x)在两个整数之间,y-1y.然后

A = abs(x) + 0.5;

之间的是y - 0.5y + 0.5.和

r =地板(一个);

等于任意一个y-1y,越近越好abs (x)

这个想法几乎适用于所有人x.然而,如果x之间的是fflintmax,数量x + 0.5不是浮点数,本身必须四舍五入到最接近的,甚至由加法硬件舍入。如果y结果是奇怪的吗一个y + 1,太大了。

所以我必须计算一个通过

A = abs(x) + (0.5 - eps/4);

的数量(0.5 - eps / 4)下一个更小的浮点数更小吗0.5

这是改进请求的结果建议.它是可用的在这里.只有行计算一个已经从第二轮改变了。

类型Round.m
函数r = round(varargin) % r = round(x)缩放并将x的元素舍入到最接近的整数。%默认值:ties,在整数中间的元素,四舍五入不为零。% % r = round(x,'even')适用于偶数。% r = round(x,'odd')与奇数绑定。% r = round(x,'up')与零的四舍五入(与默认值相同)。% r = round(x,'down')向零靠拢。% r = round(x,'plus')在数轴上是向右的。% r = round(x,'minus')在数轴上是向左的。% % r =圆(x, n)、n > = 0,轮(10 ^ n * x) / 10 ^ n,圆(12.3456,2)= 12.3500% r =圆(x - n)、n > 0, 10 ^ n * (x / 10 ^ n),圆(1234.56,2)= 1200。% r = round(x,n,'significant'), round(.001234,2,'significant') = .0012 % r = round(x,n,'decimal ')与round(x,n)相同。 % % r = round(x,...), ties, n, 'significant' and 'decimals' can be in any order. % % Use Round(...) with capital R to distinguish from built-in round(...). [x,n,ties] = parse_input(varargin{:}); x = prescale(x,n); a = abs(x) + (0.5-eps/4); r = floor(a); switch ties case 'even' m = (r == a) & (mod(r,2) == 1); case 'odd' m = (r == a) & (mod(r,2) == 0); case 'down' m = (r == a); case 'up' m = []; case 'plus' m = (x < 0) & (r == a); case 'minus' m = (x > 0) & (r == a); otherwise error(['''' ties ''' not recognized.']) end r(m) = r(m) - 1; r = sign(x).*r; r = postscale(r,n); % ---------------------------------------------- function [x,n,ties] = parse_input(varargin) x = varargin{1}; n = zeros(size(x)); ties = 'up'; for k = 2:nargin if isnumeric(varargin{k}) n(:) = varargin{k}; elseif strcmp(varargin{k},'significant') n(:) = n(:) - ceil(log10(abs(x(:)))); elseif strcmp(varargin{k},'decimals') % ignore else ties = varargin{k}; end end end function x = prescale(x,n) if any(n ~= 0) k = n > 0; x(k) = 10.^n(k).*x(k); k = n < 0; x(k) = x(k)./10.^(-n(k)); end end function r = postscale(r,n) if any(n ~= 0) k = n > 0; r(k) = r(k)./10.^n(k); k = n < 0; r(k) = 10.^(-n(k)).*r(k); end end end

测试

向量x = f: flintmax2 ^ 52 + 1元素。那是太多了。前四个和后四个就足够了。

格式十六进制x = [f + (0:3);2*f-(3:-1:0)] r = Round(x) up = Round(x,“了”)向下= Round(x,“下来”) = Round(x,“甚至”奇数=圆(x,“奇怪”) + = Round(x,“+”) - = Round(x,“-”
x = 433 433 4330000000000001 4330000000000002 4330000000000001 4330000000000000 433 ffffffffffffd ffffffffffffe fffffffffffff 4340000000000000 r = 4340000000000000 4330000000000001 4330000000000002 4330000000000001 433 433 ffffffffffffd ffffffffffffe 433 fffffffffffff 4340000000000000 = 4330000000000000 4330000000000001 43300000000000004330000000000003 433 433 ffffffffffffd ffffffffffffe 433 fffffffffffff 4340000000000000 = 432 ffffffffffffe 4330000000000000 4330000000000001 4330000000000000 433 433 ffffffffffffc ffffffffffffd 433 ffffffffffffe 433 fffffffffffff甚至= 433 4330000000000000 4330000000000002 4330000000000000 4330000000000000 433 ffffffffffffe ffffffffffffc433多ffffffffffffe 4340000000000000 = 432 ffffffffffffe 4330000000000001 4330000000000001 4330000000000001 433 433 ffffffffffffd ffffffffffffd 433 fffffffffffff 433 fffffffffffff + 433 = 4330000000000000 4330000000000001 4330000000000000 4330000000000003 433 ffffffffffffd ffffffffffffe fffffffffffff 4340000000000000 - 433 = 432 ffffffffffffe433 433 433 4330000000000000 4330000000000001 4330000000000000 433 ffffffffffffc ffffffffffffd ffffffffffffe fffffffffffff




MATLAB®R2021a发布

|

评论

请点击留下评论在这里登录到你的MathWorks帐户或创建一个新的。