Быстрый Math.round для положительных чисел
Вместо метода Math.round можно использовать следующий подход:
Этот способ работает быстрее стандартного в 30 раз. Только один минус — это будет работать только для положительных чисел. Для отрицательных чисел быстрого варианта еще не придумал.
Всего комментариев 16
Комментарии
18.01.2009 14:19 | |
Во-первых, не round, а floor для положительных и ceil для отрицательных. То есть уже возможные проблемы.
Во-вторых, int ограничен до 0x7FFFFFFF, дальше опять проблемы. |
18.01.2009 14:31 | |
Неа, как раз таки round для положительных. То, что ограничен это верно подмечено. В общем можно использовать в особо требовательных участках кода.
|
18.01.2009 16:47 | |
- А вы знаете, что 3 равно 4?
- Быть того не может! - Могу доказать, 3 + 1 = 4 Вы ерунду написали. Причем тут 0.5? |
18.01.2009 17:09 | |
18.01.2009 17:23 | |
Ааа я понял. Я увидел int/uint, а по скольку ценность round для меня равна нулю, я даже не стал рассматривать необходимость привода к нему и смысл 0.5 для меня ускользнул.
|
19.01.2009 20:51 | |
Иногда все-таки без него никак.
|
27.05.2009 20:44 | |
Яски, спасиба. Но во флэш интерпретаторе оптимизация кода кажется вообще не фурычит. Бо если код асма, то
1. добавить 0.5 (достаточно долго) 2. преобразование number в uint (очень долгая процедура в тиках) 3. mov eax, [uint value] // return 4. потом вы наверняка uint преобразовываете вновь в Number Думаю, если нет необходимости приводить к uint, то можно обойтись с помощью floor без преобразования в uint. Как Math.floor(value+0.5) для >0 (возможно, round так и устроен, только с проверкой на знаки). т.е. не утверждаю, но мож истинный |
|
Обновил(-а) Gladreaman 27.05.2009 в 20:54
|
28.05.2009 00:31 | |
Как и вдругих языках максимальный эффект дает оптимизация логики программы, настолько низкоуровневые оптимизации могут дать еще немного скорости.
|
13.10.2009 10:41 | |
для отрицательных:
var value:Number = -3.6;//-3.3 var roundValue:int = int(value - 0.5); trace (roundValue);//-4//-3 или даже: |
|
Обновил(-а) Котяра 13.10.2009 в 10:47
|
13.10.2009 11:34 | |
13.10.2009 14:01 | |
мэйби.. по мне Math.round - должен округлять до ближайшего целого, т.е. до -4
http://ru.wikipedia.org/wiki/%D0%9E%...BD%D0%B8%D0%B5 Цитата:
Округление к ближайшему целому (англ. round) — наиболее часто используемое округление. Число в десятичной системе округляют до N-ого знака в зависимости от N+1 знака:
* если N+1 знак < 5, то N-ый знак сохраняют, а N+1 и все последующие обнуляют; * если N+1 знак ≥ 5, то N-ый знак увеличивают на единицу, а N+1 и все последующие обнуляют. Например: 11,9 → 12; −0,9 → −1; −1,1 → −1; 2,5 → 3. var value:Number = -3.500000000000001;//=-4 var value:Number = -3.5000000000000001;//=-3 var roundValue:int =int(value +(value>0?.5: -.499999999999999)) trace (roundValue); trace(Math.round(value)); причем здесь тоже -3.5 -> -4 var value:Number = -3.500000000000001;//=-4 var d:int=1000000; var startTime:int = getTimer(); var a:int; var i:int; for(i=0;i<d;i++) { a=int(value +(value>0?.5: -.499999999999999)); } trace(getTimer()-startTime); startTime = getTimer(); for(i=0;i<d;i++) { a=Math.round(value); } trace(getTimer()-startTime); startTime = getTimer(); for(i=0;i<d;i++) { a=int(value.toFixed(0)); } trace(getTimer()-startTime); Цитата:
225
366 3049 то более быстрый вариант: |
|
Обновил(-а) Котяра 14.10.2009 в 14:29
|
17.12.2010 17:13 | |
Жаль, что уже не актуально. Результаты теста на сегодняшний день:
кастомный округлятор 1431 дефолтный 323 при 1кк итераций. |
Последние записи от Яски
- Инициализатор класса (05.11.2009)
- О пакетах классов (03.11.2009)
- valueOf в AS3 (07.10.2009)
- Сравнение строк в естественном порядке для Flash (18.05.2009)
- Быстрый Math.round для положительных чисел (17.01.2009)