Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #60 : 20-06-2007 13:06 » |
|
Serg79, В классе этот код просто лишний. Статичные функции не имеют this. А в остальные члены класса просто нельзя попасть легальным путем без валидного this.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #61 : 20-06-2007 14:41 » |
|
Serg79, можешь привести пример того что может стоять в скобках? внимательно присмотрись, что с NULL сравнивается.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #62 : 20-06-2007 15:40 » |
|
тут додумался до одной вещи, но подозреваю, что я не первый до неё додумался, и вот охота название этого метода узнать, если есть название. Имеется массив из N элементов типа A struct A { //содержит номер элемента 1...max. //Если ==0 , элемент пуст int index;
//что то там ешшо int n; };
#define Sz 1000
//массив A array[Sz];
//массив для запоминания индекса //(вначале массив просто обнулён) int INDX[Sz];
элементы заполняются в любом порядке, и индекс элемента совсем никак не соответствует позиции в массиве. я сделал функцию //найти элемент с индексом A* FindElem(const DWORD index_nzb) { if(index_nzb==0 || index_nzb>Sz)return 0;
A* p=0;
//сначала считаем индекс в массиве INDX правильный DWORD dwd=INDX[index_nzb-1];
//берём из array элемент, но проверяем на правильность, //сравнивая его .index с "заказанным" index_nzb if(dwd<Sz) { //смотрим, тот ли номер if(array[dwd-1].index==index_nzb) { //значение INDX[dwd-1] было верным return p; } }
//значение INDX[dwd-1] неверное //ищем элемент и корректируем for(dwd=0;dwd<Sz;dwd++) { if(array[dwd-1].index==index_nzb) { //нашли //корректируем индекс на следующий раз INDX[index_nzb-1]=dwd; return p; } }
//ничего не нашли return 0; }
то есть, чтоб каждый раз не перебирать весь массив в поисках нужного элемента, элемент ищется один раз, а потом используется "запомненное положение" А если положение запомнено неверно (мували элемент), снова поиск производится. Второй раз элемент находится в момент Как такой метод зовётся ? ------------- кстати, код неработоспособен - не проверял я его , да и так вижу. Всё равно под конкретный случай своё будет. Но идея мне всё равно нравится ))
|
|
« Последнее редактирование: 06-12-2007 18:41 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #63 : 24-07-2007 09:44 » |
|
форматирование типа __int64 (долго ловил глюк, пытаясь вывести напрямую в %u или %x ) //форматирование 64 битной переменной в десятичном виде #define def_FormatU64dec(textbefore,cs,val64,textafter) \ {\ DWORD dwdDiv=1000000000;\ DWORD dwdHHpart =(DWORD)( ((unsigned __int64)(val64)) /dwdDiv/dwdDiv);\ DWORD dwdHpart =(DWORD)( ((unsigned __int64)(val64)) /dwdDiv%dwdDiv);\ DWORD dwdLpart =(DWORD)( ((unsigned __int64)(val64)) %dwdDiv);\ if(dwdHHpart)\ {\ cs.Format("%s%u%09u%09u%s",\ textbefore,\ dwdHHpart,\ dwdHpart,\ dwdLpart,\ textafter);\ }\ else\ if(dwdHpart)\ {\ cs.Format("%s%u%09u%s",\ textbefore,\ dwdHpart,\ dwdLpart,\ textafter);\ }\ else\ {\ cs.Format("%s%u%s",\ textbefore,\ dwdLpart,\ textafter);\ }\ }
//форматирование 64 битной переменной в HEX виде #define def_FormatU64hex(textbefore,cs,val64,textafter) \ {\ unsigned __int64 qw=(val64);\ cs.Format("%s%x%08x%s",\ textbefore,\ *(((DWORD*)&qw)+1),\ *(((DWORD*)&qw)+0),\ textafter);\ }
|
|
« Последнее редактирование: 27-09-2007 05:20 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #64 : 27-09-2007 04:12 » |
|
результаты небольшого экспериента по скорости работы: для типа CString при формировании строки из нескольких переменных CString гораздо "быстрее выполняется" процедура Format, чем оператор + . CString t1,t2,t3; t2="222222222222"; t3="333333333333";
DWORD res; DWORD dwd1,dwd2; int i;
enum { e_iterz=100000, };
dwd1=::GetTickCount(); for(i=0;i<e_iterz;i++) { t1.Format("__%s__%s__",t2,t3); } dwd2=::GetTickCount(); res=dwd2-dwd1; t1.Format("форматирование, T ~ %u мс ",res); MessageBox(t1);
//сложение dwd1=::GetTickCount(); for(i=0;i<e_iterz;i++) { t1="__"+t2+"__"+t3+"__"; } dwd2=::GetTickCount(); res=dwd2-dwd1; t1.Format("сложение, T ~ %u мс ",res); MessageBox(t1);
результаты на моей машине: "форматирование" выполнено за ~157 мс "сложение" выполнено за ~484 мс И ещё любопытная деталь: для выражений вида t1.Format("%s%s",t2,t3); и t1=t2+t3;
время практически одинаковое, причём второе даже иногда чуточку быстрее
|
|
« Последнее редактирование: 27-09-2007 05:48 от Алексей1153++ »
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #65 : 27-09-2007 05:02 » |
|
а пробовал тоже самое, но с предварительным резевированием места в результирующей строке?
|
|
|
Записан
|
Странно всё это....
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #66 : 27-09-2007 05:03 » |
|
LogRus, это как ? вроде txt.GetBufferSetLength(t1.Get t2.GetLenght()+t3.GetLenght())
? только это не всегда удобно и, кажется, может даже медленнее работать, ведь цикл был приведён для оценки времени , а реально GetBufferSetLength() будет как бы в цикле тоже находиться
|
|
« Последнее редактирование: 27-09-2007 05:07 от Алексей1153++ »
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #67 : 27-09-2007 05:36 » |
|
за цикл вынеси и установи размер гарантированно больший размера результирующей строки.
и былобы не плохо увидеть std::string
|
|
|
Записан
|
Странно всё это....
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #68 : 27-09-2007 05:46 » |
|
LogRus, 1)добавил перед циклами t1.GetBufferSetLength(1000); время не изменилось в обоих случаях 2) с std::string не знаком
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #69 : 27-09-2007 06:48 » |
|
Алексей1153++, так это нормальная ситуация можешь даже посмотреть откомпилированный код и увидишь что при "+" появляются еще вызовы различных функций.
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #70 : 27-09-2007 08:48 » |
|
А студия какая? В последних MFC CString работает через ATL.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #71 : 27-09-2007 09:05 » |
|
VC6
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #72 : 22-11-2007 04:59 » |
|
было написано в программе на с++ : DWORD dwd dwd=(0x00000001 << nTextData);
предполагалось, что если nTextData больше 32, то результат будет 0 , ан неет... Заглянул в ассемблерный код и поэкспериментировал, оказалось что команда shl (а также shr , а ещё другие команды сдвига наверное тоже) работают не так а так !! то есть при значении nTextData==33 , в dwd получится значение 2 , а не 0 это так всегда и было, или это глюк ? Всегда думал , что бит должен просто уехать и в результате получиться 0
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #73 : 22-11-2007 09:55 » |
|
3 The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined. Фича твоего компилятора. Не советую такие "мины" в код закладывать.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #74 : 22-11-2007 10:12 » |
|
dimka, дык... Я и не закладываю, просто не знал. Сейчас рою весь код и делаю вроде этого: res = ((shift>=sizeof(source)*8) ? 0 : source<<shift);
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #75 : 22-11-2007 14:19 » |
|
Сейчас рою весь код и делаю вроде этого: Це ж C++, а не C... Я ленивый, я бы сперва попробовал оператор "<<" переопределить безопасным образом, прежде чем весь код рыть...
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #76 : 22-11-2007 14:31 » |
|
я тоже ленивый, но в таких вещах мне не лень Переопределить как раз неохота - почему то не люблю глобальные вещи переопределять...
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #77 : 14-12-2007 05:20 » |
|
всем известна такая фишка (в студии, по крайней мере) - для того, чтобы инклудить файл, лежащий не в текущей папке проекта, а на шаг выше, надо написать
#include "..\myfile.h"
оказывается, веселуху можно продолжить -
#include "..\..\..\myfile.h" - если файл лежит на 3 шага выше
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #78 : 14-12-2007 07:36 » |
|
случайно обнаружил - если в блокноте нажать F5 , то вставляется текущее время и дата
|
|
|
Записан
|
|
|
|
DemonicAlligator
Гость
|
|
« Ответ #79 : 14-12-2007 09:39 » |
|
в MidnightCommander у редактора свои настройки распознавания клавиш... собсьна и редактор-то называеца mcedit
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #80 : 14-12-2007 09:45 » |
|
Синий Аллигатор, я говорю именно про мелкомягкий блокнот , командерами всякими не пользуюсь как-то )
|
|
|
Записан
|
|
|
|
DemonicAlligator
Гость
|
|
« Ответ #81 : 14-12-2007 11:19 » |
|
а я про линуксовый mc
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #82 : 14-12-2007 12:34 » |
|
всем известна такая фишка (в студии, по крайней мере) - для того, чтобы инклудить файл, лежащий не в текущей папке проекта, а на шаг выше, надо написать
#include "..\myfile.h"
оказывается, веселуху можно продолжить -
#include "..\..\..\myfile.h" - если файл лежит на 3 шага выше
плохой стиль. правильней прописать дополнительный каталог для инклюдов.
|
|
|
Записан
|
Странно всё это....
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #83 : 14-12-2007 12:38 » |
|
LogRus, знаю, что плохой ) Я так не использую , только вложенные. Когда то пытался с одним шагом наверх - что то меня тогда смутило , что то не так работало. Не помню уже
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #84 : 21-12-2007 13:31 » |
|
Недавно, ради разминки, написал програмку, которая ишет "Идеальные числа". В математике этот термин обозначает, что у такого числа, если сложить все делители данного числа, то результат сложения будет само число. Например число 6. Его делители 1, 2, 3. Сумма делителей будет число 6. Вот собственно код: #include <stdio.h>
bool IsIdeal(int m) { int sum = 1, down=2, up=m/down;; while (down<up) { if(m%down == 0) sum += down+up; down++; up=m/down;
}
return (sum==m); }
int main() {
for(int i=2; i<=1000000; i++) { if (IsIdeal(i)) printf("%d\n", i); } return 0; }
Запустил у себя и получил результат и время работы $ time ./main 6 28 496 8128
real 0m24.961s user 0m24.962s sys 0m0.000s $ time ./main 6 28 496 8128
real 0m24.969s user 0m24.962s sys 0m0.000s $ time ./main 6 28 496 8128
real 0m24.972s user 0m24.970s sys 0m0.000s
Как видим, среднее время работы по строчке user 24.965 секунды. Чуть модернизируем программу. #include <stdio.h>
bool IsIdeal(int m) { int sum = 1, down=2, up=m/down;; while (down<up) { if(up*down == m) sum += down+up; down++; up=m/down;
}
return (sum==m); }
int main() {
for(int i=2; i<=1000000; i++) { if (IsIdeal(i)) printf("%d\n", i); } return 0; }
Поменял только if(m%down == 0) на if(up*down == m). Также запускаем с засечкой времени. $ time ./main 6 28 496 8128
real 0m13.938s user 0m13.937s sys 0m0.004s $ time ./main 6 28 496 8128
real 0m14.073s user 0m14.069s sys 0m0.000s $ time ./main 6 28 496 8128
real 0m14.202s user 0m14.069s sys 0m0.004s
Получаем среднее время работы 14,025 секунд. Я конечно знал, что операция деления более весомая, чем все остальные простые операции. Но увеличение скорости произошло практически в два раза
|
|
« Последнее редактирование: 21-12-2007 13:41 от Finch »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #85 : 21-12-2007 16:03 » |
|
я как-то реализовывал операцию деления в VisSim на простых логических элементах - И, ИЛИ, НЕ . Сделал деление 4-битных чисел , при этом было использовано около 200 элементов )) На бОльшие разрядности терпежу не хватило - суть я понял, поэтому не стал дальше развивать а умножение намного проще: abcd*efgh == операция bit1 + bit2 собрана из элементов (bit1 XOR bit2) и один перенос(если bit1 AND bit2) - это 2 простых элемента операция bit1 * bit2 собрана из элементов (bit1 AND bit2) - это 1 простой элемент далее при помощи уже готовых элементов "+" и "*" : abcd * efgh ------------------------------------ a*h b*h c*h d*h + a*g b*g c*g d*g + a*f b*f c*f d*f + a*e b*e c*e d*e -----------------------------------
0 бит : d*h (и один перенос C0_1) 1 бит : C0_1 + c*h + d*g (и два переноса C1_1 , C1_2) ..... в общем, элементов тоже немало , но поменьше, чем в делении ) И тактов меньше тратится (наверное - как раз в 2 раза и меньше тактов)
|
|
« Последнее редактирование: 21-12-2007 16:05 от Алексей1153++ »
|
Записан
|
|
|
|
Scorp__)
Молодой специалист
Offline
Пол:
|
|
« Ответ #86 : 21-12-2007 19:28 » |
|
Finch, там по тактам как раз в два раза примерно и получается. Вот интересно было бы посмотреть результаты с полностью вытянутой оптимизацией. В 2003-ей студии была возможность оптимизировать под конкретный процессор, в 2005-й я этого не нашел, но оптимизацию компилятора можно было бы включить.
|
|
|
Записан
|
- А Вы сами-то верите в привидения? - Конечно, нет, - ответил лектор и медленно растаял в воздухе.
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #87 : 21-12-2007 20:41 » |
|
Ну это все я прогонял на gcc. Код в двух случаях был скомпилирован в режиме дебага. Сейчас его скомпилировал в режиме полной оптимизации. Правда в код добавил одну проверку еше. bool IsIdeal(int m) { int sum = 1, down=2, up=m/down;; while (down<=up) { if(up*down == m) { if (up == down) sum+=up; else sum += down+up; } down++; up=m/down;
}
return (sum==m); }
Как результат оптимизации, улучшение скорости работы практически на секунду. И среднее время составляет 12,846 секунд
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Scorp__)
Молодой специалист
Offline
Пол:
|
|
« Ответ #88 : 21-12-2007 21:22 » |
|
Мда, 7% не так уж и много Никакая оптимизация не помогает, если использовать тяжелые инструкции
|
|
|
Записан
|
- А Вы сами-то верите в привидения? - Конечно, нет, - ответил лектор и медленно растаял в воздухе.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #89 : 23-01-2008 06:52 » |
|
любопытная вещица: если послать окну не стандартное сообщение (например WM_USER+2000) тосообщение не виднО в Spy++, однако в процедуре окна PreTranslateMessage() сообщение прекрасно ловится
|
|
|
Записан
|
|
|
|
|