如何在MATLAB中更改浮点运算的舍入模式?

问题描述 投票:6回答:1

我想在MATLAB中更改浮点运算的舍入模式。根据IEEE 754-2008,有五种舍入策略:

  • 四舍五入到最近,与偶数相关
  • 圆到最近,从零开始
  • 向零舍入
  • 向上(向正无穷大)
  • 向下舍入(向负无穷大)

MATLAB是否支持这5种策略?如何在MATLAB中更改浮点运算的舍入模式?

matlab floating-point rounding
1个回答
3
投票

回答

的种类。有一个无证的feature('setround')函数调用,您可以使用它来获取或设置Matlab使用的舍入模式。

所以,它可以做到,但你不应该这样做。 :)

警告:这是一个未记录的,不受支持的功能!使用自负!

这个feature('setround')支持5种IEEE-754舍入模式中的4种:只有一种“最近”模式,我不知道它是“与偶数相关联”还是“与零相关”。

支持的模式:

  • feature('setround') - 获取当前的舍入模式
  • feature('setround', 0.5) - 向最近的方向舍入(不知道它是否与偶数或远离零的关系)
  • feature('setround', Inf) - 向上(向+ Inf)
  • feature('setround', 0) - 向零回合
  • feature('setround', -Inf) - 向下舍入(朝-Inf)

关于测试的注意事项:IEEE-754舍入模式不会影响round()及其亲属。相反,它控制算术运算在浮点精度极限附近的行为方式。

示范

%ROUNDINGEXAMPLE Demonstrates IEEE-754 Rounding Mode control
%
% This uses a completely undocumented and unsupported feature!
% Not for production use!

%% Setup
clear; clc

n = 2000;
X = ones(n)*1E-30; % matrix with n^2 elements
defaultRoundingMode = feature('setround'); % store default rounding mode

%%
feature('setround',0.5);
r1 = prettyPrint('Nearest', sum(X(:)));
%{
  sign   exponent                       mantissa
     0 01110110001 0011010101111100001010011001101001110101010000011110
     | \_________/ \__________________________________________________/
     |      |             ______________________|___________________________
     |      |            /                                                  \
(-1)^0 2^( 945 - 1023) 1.0011010101111100001010011001101001110101010000011110 = 4e-24
%}

%%
feature('setround',-Inf);
r2 = prettyPrint('To -Infinity', sum(X(:)));
%{
  sign   exponent                       mantissa
     0 01110110001 0011010101111100001010011001101001011100000111000110
     | \_________/ \__________________________________________________/
     |      |             ______________________|___________________________
     |      |            /                                                  \
(-1)^0 2^( 945 - 1023) 1.0011010101111100001010011001101001011100000111000110 = 4e-24
%}

%%
feature('setround',Inf);
r3 = prettyPrint('To Infinity', sum(X(:)));
%{
  sign   exponent                       mantissa
     0 01110110001 0011010101111100001010011001101010100011101100100001
     | \_________/ \__________________________________________________/
     |      |             ______________________|___________________________
     |      |            /                                                  \
(-1)^0 2^( 945 - 1023) 1.0011010101111100001010011001101010100011101100100001 = 4e-24
%}

%%
feature('setround',0);
r4 = prettyPrint('To zero', sum(X(:)));
%{
  sign   exponent                       mantissa
     0 01110110001 0011010101111100001010011001101001011100000111000110
     | \_________/ \__________________________________________________/
     |      |             ______________________|___________________________
     |      |            /                                                  \
(-1)^0 2^( 945 - 1023) 1.0011010101111100001010011001101001011100000111000110 = 4e-24
%}

%%
feature('setround',defaultRoundingMode);
r5 = prettyPrint('No accumulated roundoff error', 4e-24);
%{
  sign   exponent                       mantissa
     0 01110110001 0011010101111100001010011001101010001000111010100111
     | \_________/ \__________________________________________________/
     |      |             ______________________|___________________________
     |      |            /                                                  \
(-1)^0 2^( 945 - 1023) 1.0011010101111100001010011001101010001000111010100111 = 4e-24
%}

%% Helper function
function r = prettyPrint(s, r)
    fprintf('%s:\n%65.60f\n\n', s, r); 
end

我明白了:

Nearest:
   0.000000000000000000000003999999999966490758963870373537264729

To -Infinity:
   0.000000000000000000000003999999999789077070014108839608005726

To Infinity:
   0.000000000000000000000004000000000118618095059505975310731249

To zero:
   0.000000000000000000000003999999999789077070014108839608005726

No accumulated roundoff error:
   0.000000000000000000000003999999999999999694801998206811298525

致谢

感谢MathWorks技术支持部门的Ryan Klots让我直截了当地提供了很好的演示代码!

© www.soinside.com 2019 - 2024. All rights reserved.