Binary operations with different scalar scalar types

Using a dev octave 7.0.1

a = 1 + uint8(1) % valid

a = uint16(1) + uint8(1) % not valid
error: binary operator ‘+’ not implemented for ‘uint16 scalar’ by ‘uint8 scalar’ operations

a = uint32(1) + uint16(1) % not valid etc

An intentional change ?

Was that different before?

hmmm … maybe? I hadnt noticed it until now I guess when I saw the audio package was failing some tests, but yeah looks like behaving the same. My fix was to ensure both values are the same type which fixed the issue, and then I saw the error message … :slight_smile:

for the audio package it works ok for me using 6.3.1 but running using 7 it fails.

The function was (after modified for testing):

function t = getvariable (fd)
  t = uint64(0);
  while !feof(fd)
    b = fread(fd, 1, "uint8");
    c = bitand(b, 0x7f);
    d = bitshift(t, 7);
    whos t b c d
    t = d + c;
    if b < 128
      break;
    endif
  endwhile
  t = double(t);
endfunction

When running in 6.3.1 the whos shows:

  Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
    f   t           1x1                          8  uint64
        b           1x1                          8  double
        c           1x1                          8  double
        d           1x1                          8  uint64

And all works

In octave 7.0:


  Attr   Name        Size                     Bytes  Class
  ====   ====        ====                     =====  ===== 
    f    t           1x1                          8  uint64
         b           1x1                          8  double
         c           1x1                          1  uint8
         d           1x1                          8  uint64

With an error then

error: binary operator ‘+’ not implemented for ‘uint64 scalar’ by ‘uint8 scalar’ operations

On the t = d + c; line - so lloking at changes in type, its really:

c = bitand(b, 0x7f);

That returns the same type as the input rather than double now. Although when running as a single input in both versions, i dont see it as a double - so I may be missing something obvious.

In octave 6.3, a = bitand(double(10), 0x7f) returns a double type

octave:7> a = bitand(double(10), 0x7f)
a = 10
octave:8> whos
Variables visible from the current scope:

variables in scope: top scope

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        a           1x1                          8  double

Total is 1 element using 8 bytes

In octave 7.0 a = bitand(double(10), 0x7f) return as a uint8

octave:1> a = bitand(double(10), 0x7f)
a = 10
octave:2> whos
Variables visible from the current scope:

variables in scope: top scope

  Attr   Name        Size                     Bytes  Class
  ====   ====        ====                     =====  ===== 
         a           1x1                          1  uint8

Total is 1 element using 1 byte

In Matlab R2021a:

>> bitand(double(10), uint8(10))
ans =
  uint8
   10

So, the behavior in Octave 7 is compatible.

The root difference might be that hexadecimals are now an integer type in Octave.
Octave 6.4.0:

>> class(0x7f)
ans = double

Octave 7.0.1:

>> class(0x7f)
ans = uint8

There is this note related to this change in the NEWS file:

  • Binary and hexadecimal constants like 0b101 and 0xDEADBEEF now
    create integers (unsigned by default) with sizes determined from the
    number of digits present. For example, 0xff creates a uint8 value
    and 0xDEADBEEF creates a uint64 value. You may also use a suffix of
    the form u8, u16, u32, u64, s8, s16, s32, or s64 to
    explicitly specify the data type to use (u or s to indicate unsigned
    or signed and the number to indicate the integer size).

ok- had missed the news change. I’ll change my code appropriately.

Thanks!