Показать сообщение отдельно
Старый 01.08.2014, 01:07
nubideus вне форума Посмотреть профиль Отправить личное сообщение для nubideus Найти все сообщения от nubideus
  № 8  
Ответить с цитированием
nubideus

Регистрация: Jan 2013
Сообщений: 322
(все таки сортировка это n*log(n))

в варианте с abs есть баг. [5, 4], 4.5 - с такими значениями выдаст 5, а должно 4.
в варианте от caseyryan есть еще один, если первый элемент массива будет нулем, то работать не будет.

долго упарывался и родил это
Код AS3:
private function nearestSearch(arr:Vector.<Number>, v:Number):Number {
	var pos:Number = Infinity;
	var neg:Number = -Infinity;
	var eps:Number = 2.220446049250313e-16;
	for (var i:uint = 0; i < arr.length; i++) {
		var el:Number = arr[i];
		if ((el - pos) * (el - v + eps) < 0) pos = el;
		if ((el - neg) * (el - v - eps) < 0) neg = el;
	}
	return (v - neg > pos - v) ? pos : neg;
}
быстрее abs примерно на 30%.
без эпсилонов код будет игнорировать элементы, равные v.

суть в том, что оно по идее должно делать то же, что и:
Код AS3:
if (arr[i] - v >= 0 && arr[i] < pos) pos = arr[i];
if (v - arr[i] >= 0 && neg < arr[i]) neg = arr[i];
код asb(с багом):
Код AS3:
private function nearestSearch(arr:Vector.<Number>, v:Number):Number {
	var result:Number = NaN;
	var minAbs:Number = Infinity;
	for (var i:uint = 0; i < arr.length; i++) {
		var diff:Number = arr[i] - v;
		var abs:Number = diff < 0 ? -diff : diff;
		if (abs < minAbs) {
			minAbs = abs;
			result = arr[i];
		}
	}
	return result;
}
все благодаря тому, что (mid - right) * (mid - left) <= 0 делает так: left >= mid && mid <= right || right >= mid && mid <= left.