Matlab: How to properly get a mask equivalent to 2^63-1?

251 views Asked by At

I'm having some problems with MATLAB and 64-bit integers. I want to have a mask equivalent to 2^63-1 (all ones except the MSB), but MATLAB just seems to round everything.

>> mask_fraction = uint64(9223372036854775807)

mask_fraction = 9223372036854775808 % This is 2^63 again, not 2^63-1!

Similarly,

  >> uint64(2^63)

    ans =  9223372036854775808       


    >> uint64(2^63-1)

    ans =  9223372036854775808

Another one of my attempts simply doesn't work:

>> uint64(2^63) - 1
??? Undefined function or method 'minus' for input arguments of type 'uint64'.

Thoughts?

4

There are 4 answers

1
Bas Swinckels On

It seems from the other comments that Matlab does not implement the minus method for class uint64 in some older versions. The ugly workaround below works for me in R2011b:

>> bitset(intmax('uint64'), 64, 0)

ans =

  9223372036854775807
1
Bas Swinckels On

I don't see the problems you report. On my computer (Matlab R2012b on 64-bit Ubuntu12.04):

>> mask_fraction = uint64(9223372036854775807)

mask_fraction =

  9223372036854775807

>> uint64(2^63) - 1

ans =

  9223372036854775807

Do you maybe run an older Matlab version?

I also find the 'undefined function or method minus ...' error a bit suspicious. Do you have uint64 aliased to some other function? Try clear uint64 first ...

1
Mohsen Nosratinia On

I don't know if it is supported by the version of MATLAB you are using but this might help

mask_fraction = uint64(intmax('int64'))

which returns

mask_fraction =
  9223372036854775807

2^63-1 is the maximum value for int64.

0
horchler On

@BasSwinckels correctly points out one issue. I'll address another.

The first non-exactly representable double-precision floating point integer is 2^53+1. When you pass in expressions to the uint64 function they are evaluated as doubles before being cast to uint64. If these expressions evaluate to a double precision integer that is not exactly representable, you'll see behavior like you described. This is exactly why uint64(2^63-1) and uint64(2^63) both return 9223372036854775808. All powers of two can be safely represented in double precision, so uint64(2^63)-1 or uint64(2^63)-uint64(1) are what you should use (once you figure out your other issue).