如何禁用MatLab整数溢出饱和以获得带符号环绕

iugsix8n  于 2022-11-15  发布在  Matlab
关注(0)|答案(4)|浏览(140)

我想测试一个函数,从127开始,127+1=-128对我来说是正常的。但对于MatLab来说,它会使我的值饱和,即使这是我的代码中需要的行为。
有一些解释可以在Simulink上禁用该选项,但是对于脚本呢?我不知道如何禁用此功能。

z8dt9xmd

z8dt9xmd1#

溢出不是MatLab假设的一部分。您需要使用the modulo function (mod)在脚本中实现此行为。例如:

>> a=127; mod(a+128,256)-128

ans =

   127

>> a=128; mod(a+128,256)-128

ans =

  -128
s5a0g9ez

s5a0g9ez2#

由于您使用127和-128作为示例,因此我假设您使用的是int8变量类型。为了获得您想要的模运算行为,您可以使用一个简单的C Mex例程来进行算术运算(因为您的C编译器很可能会将这种溢出条件优化为简单的模运算行为),或者在m代码中,您可以将其转换为较大的类型并自己进行运算(假设您的机器对整数类型使用2的补码存储)。例如,

a8 = int8(127); % sample data
b8 = int8(1); % sample data
a16 = int16(a8); % convert to larger type
b16 = int16(b8); % convert to larger type
c16 = a16 + b16 % do the addition in larger type
    c16 = int16
        128
c8s = typecast(c16,'int8') % typecast back to int8 (assume 2's complement storage)
    c8s = 1x2
       -128    0
c8 = c8s(1) % pick either c8s(1) or c8s(2) depending on endian of your machine
    c8 = int8
       -128

如果您使用的是数字数组而不是标量数组,那么可以将其放入循环中,或者将最后一行向量化为c8(1:2:end)或c8(2:2:end)

cbjzeqam

cbjzeqam3#

您可以使用Fixed-Point toolbox中的fi对象,并将OverflowAction设置为Wrap
使用fi应用溢出的int8类型有点矫枉过正,但也是可能的。
示例:

x = fi(127, true, 8, 0, 'OverflowAction', 'Wrap', 'SumMode', 'SpecifyPrecision', 'SumWordLength', 8, 'SumFractionLength', 0);

x + 1

产出:

ans = 

  -128

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 8
        FractionLength: 0

        RoundingMethod: Nearest
        OverflowAction: Wrap
           ProductMode: FullPrecision
               SumMode: SpecifyPrecision
         SumWordLength: 8
     SumFractionLength: 0
         CastBeforeSum: true
fkvaft9z

fkvaft9z4#

如果您确实想使用int8溢出,而不是使用mod函数来模拟它,您可以使用typecast函数。
首先,您需要将变量转换为int(否则在MatLab中默认为double)。然后将其转换为int8,并且只保留第一个字节:

>> a=127; getfield(typecast(int64(a),'int8'),{1})

ans =

  int8

   127

>> a=128; getfield(typecast(int64(a),'int8'),{1})

ans =

  int8

   -128

相关问题