我处理图像,然后按其最大值(在这种情况下为3165)对其进行标准化。
经过一些工作,我想用像素的原始值做一些操作,所以我再乘以3165。
问题在于,由于数字精度,并非所有像素都返回其整数值。 例如,考虑值为30的像素:
a=30/3165
a =
0.0095
>> b=a*3165
b =
30.0000
>> b-30
ans =
3.5527e-15
错误本身非常小,但我需要将它用作其他向量的索引,显然它不起作用。
从技术上讲,我可以在乘法后使用round
。这是一个很好的解决方案,但很难看,并不是解决这个问题的合适方式和良好做法。
有人有其他(更专业)的想法吗?或者这是这样做的方法吗?
感谢。
答案 0 :(得分:2)
下面提到的技术使用eps
和fix
。这些可能更少" uglier"比rounding
更适合你的情况。让我们一步一步地查看这些代码和注释。
%%// Original indices
org_indices = [15 30 45 60]
%%// Scaled indices
scaled_indices = org_indices/3165
%%// Retrieved indices that are yet to be converted to exact integers
retrieved_indices = scaled_indices*3165
%%// Verify precision issue
check_ind1 = retrieved_indices(1) - 15
check_ind1
输出 1.7764e-15
,并且不完全为零。
我们可以使用根据官方MATLAB文档说的eps - 如果d = eps(X),则d是从abs(X)到下一个更大的浮点数的正距离精度为X。
因此,我们可以如下计算这样的距离/偏移 -
eps_val = eps(retrieved_indices)
eps_val
可以被视为窗口向量,用于确定元素所在的窗口向量,必须对应于也位于其中的整数。为了方便我们,我们可以使用这些窗口中的最大值进行决策,并使其非常安全,我们可以将此宽度增加10倍,并将其称为max_window_width -
max_window_width = 10*max(eps_val)
这并不像舍入一样丑陋,因为舍入使用的窗口长度为1
,因为它的范围为[-0.5 0.5]
,而这个窗口长度为7.1054e-14
。
最后,我们可以通过添加此最大宽度然后使用fix
截断小数部分来获取原始索引 -
retrieved_indices2 = fix(retrieved_indices + max_window_width)
可以检查精确度值 -
check_ind2 = retrieve_indices2(1) - 15
check_ind2
输出 0
。