Type conversion happens before matlab Set method is called in classes, problem with setting int64(Nan) = [] default is 0
Show older comments
I am trying to set the default behaviour of a class so that int64(NaN) is set to empty and Not to the default 0.
Here is a simple class example class example:
classdef TestClass < matlab.mixin.SetGet
% CLASSDEF TestClass class to test add NaN
%
properties
a int64 {mustBeNonNan} = []
end % methods
methods
function obj = TestClass()
end % TestClass
function set.a(obj, val)
disp(val)
class(val)
obj.a = val;
end
end % methods
end % class
If you try and set a = Nan here it gets set to 0, in the set method it is already a int64 and not a double NaN. Is there a way to change this? I don't really want to addListeners and handle preSet methods. I also want the class type to be an int64 rather than not give it a type and then set the type in the set method.
On another note why is int64(NaN) set to 0 anyway?
This would work, but then the class property would not be an int64.
classdef TestClass < matlab.mixin.SetGet
% CLASSDEF TestClass class to test add NaN
%
properties
a
end % methods
methods
function obj = TestClass()
obj.a = int64([]);
end % TestClass
function set.a(obj, val)
if isnan(val), val = []; end
obj.a = int64(val);
end
end % methods
end % class
4 Comments
Matt J
on 28 Nov 2022
On another note why is int64(NaN) set to 0 anyway?
Integer types can't represent NaNs. What bit pattern would you choose to represent it? Whichever you choose, it would sacrifice one of the finite integers that int64 will normally hold for you.
Having myInt64(NaN) (where myInt64 is your class name) return [] instead of 0 will cause problems when or if you start working with arrays. If you replaced int64 in the example below with the constructor of your int64-like class, do you want the variable a to be a "jagged" array? That doesn't open a can of worms, it opens a 55 gallon drum of worms.
a = int64([1 2; 3 NaN])
Matt J
on 28 Nov 2022
I also want the class type to be an int64 rather than not give it a type and then set the type in the set method.
I don't see why you would prefer that. One is just a shorthand for the other.
Benjamin Klein
on 28 Nov 2022
Answers (2)
Matt J
on 28 Nov 2022
One possibility:
>> obj=myclass; obj.a=1:5, obj.a(2)=nan
obj =
myclass with properties:
a: [1 2 3 4 5]
obj =
myclass with properties:
a: [1 3 4 5]
classdef myclass < matlab.mixin.SetGet
% CLASSDEF TestClass class to test add NaN
%
properties
a
end % methods
methods
function set.a(obj, val)
val(isnan(val))=[];
obj.a = int64(val);
end
function val=get.a(obj)
val=double(obj.a);
end
end % methods
end % class
Matt J
on 28 Nov 2022
Another approach, using subsasgn(). This one avoids conversion of obj.a to double.
>> obj=myclass; obj.a=1:5, obj.a(2)=nan
obj =
myclass with properties:
a: [1 2 3 4 5]
obj =
myclass with properties:
a: [1 3 4 5]
classdef myclass < matlab.mixin.SetGet
% CLASSDEF TestClass class to test add NaN
%
properties
a int64
end % methods
methods
function obj=subsasgn(obj,S,val)
obj=builtin('subsasgn',obj,S,val);
if strcmp(S(1).type,'.') && strcmp(S(1).subs,'a')
b=false(size(obj.a));
if numel(S)>1
b(S(2).subs{:})=isnan(val);
else
b=isnan(val);
end
obj.a(b)=[];
end
end
end % methods
end % class
Categories
Find more on Construct and Work with Object Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!