How does im2int16 map double(0.5) to int16(0)?
I’ve known about this for a long time, and I’ve ignored it. It’s a curiosity I pick at every time I edit MIMT imcast(), but I’ve never really figured out a good explanation.
IPT im2int16() maps floating point values on the unit interval to values on the interval [-32768 32767]. That seems very simple. The problem is that obvious arithmetic doesn’t give the same result. What’s more curious is that it seems that the only input value that does not map identically is 1/2.
% our input
dx = 3E-5;
x = [0 linspace(0.5-dx,0.5+dx,7) 1].’; % ‘single’ or ‘double’ are the same
% convert it
y1 = im2int16(x); % the curiosity
y2 = int16(double(x)*65535 – 32768); % the obvious
y3 = int16(rescale(x,-32768,32767,’inputmin’,0,’inputmax’,1)); % a third opinion
% compare
[y1 y2 y3]
For what it’s worth, im2double() doesn’t map that 0 back to 1/2. It maps exactly like one would expect.
% map back to float
z1 = im2double(y1(2:8));
z2 = ((double(y2(2:8)) + 32768)/65535 );
% compare error
[z1 z2] – x(2:8)
So I suppose I have three sorts of questions.
How does this happen? I’m assuming this rises naturally from some simple conversion being used, but im2int16() isn’t working in mcode, and I’m not the clever one here.
Do you think this should be expected? Matter of differing conventions? Preference?
Does it really even matter? I’ve been assuming it doesn’t.I’ve known about this for a long time, and I’ve ignored it. It’s a curiosity I pick at every time I edit MIMT imcast(), but I’ve never really figured out a good explanation.
IPT im2int16() maps floating point values on the unit interval to values on the interval [-32768 32767]. That seems very simple. The problem is that obvious arithmetic doesn’t give the same result. What’s more curious is that it seems that the only input value that does not map identically is 1/2.
% our input
dx = 3E-5;
x = [0 linspace(0.5-dx,0.5+dx,7) 1].’; % ‘single’ or ‘double’ are the same
% convert it
y1 = im2int16(x); % the curiosity
y2 = int16(double(x)*65535 – 32768); % the obvious
y3 = int16(rescale(x,-32768,32767,’inputmin’,0,’inputmax’,1)); % a third opinion
% compare
[y1 y2 y3]
For what it’s worth, im2double() doesn’t map that 0 back to 1/2. It maps exactly like one would expect.
% map back to float
z1 = im2double(y1(2:8));
z2 = ((double(y2(2:8)) + 32768)/65535 );
% compare error
[z1 z2] – x(2:8)
So I suppose I have three sorts of questions.
How does this happen? I’m assuming this rises naturally from some simple conversion being used, but im2int16() isn’t working in mcode, and I’m not the clever one here.
Do you think this should be expected? Matter of differing conventions? Preference?
Does it really even matter? I’ve been assuming it doesn’t. I’ve known about this for a long time, and I’ve ignored it. It’s a curiosity I pick at every time I edit MIMT imcast(), but I’ve never really figured out a good explanation.
IPT im2int16() maps floating point values on the unit interval to values on the interval [-32768 32767]. That seems very simple. The problem is that obvious arithmetic doesn’t give the same result. What’s more curious is that it seems that the only input value that does not map identically is 1/2.
% our input
dx = 3E-5;
x = [0 linspace(0.5-dx,0.5+dx,7) 1].’; % ‘single’ or ‘double’ are the same
% convert it
y1 = im2int16(x); % the curiosity
y2 = int16(double(x)*65535 – 32768); % the obvious
y3 = int16(rescale(x,-32768,32767,’inputmin’,0,’inputmax’,1)); % a third opinion
% compare
[y1 y2 y3]
For what it’s worth, im2double() doesn’t map that 0 back to 1/2. It maps exactly like one would expect.
% map back to float
z1 = im2double(y1(2:8));
z2 = ((double(y2(2:8)) + 32768)/65535 );
% compare error
[z1 z2] – x(2:8)
So I suppose I have three sorts of questions.
How does this happen? I’m assuming this rises naturally from some simple conversion being used, but im2int16() isn’t working in mcode, and I’m not the clever one here.
Do you think this should be expected? Matter of differing conventions? Preference?
Does it really even matter? I’ve been assuming it doesn’t. im2int16 MATLAB Answers — New Questions