Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите разобраться в коде! 
V
    Опции темы
SashaOSC
Дата 26.4.2008, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



Помогите расшифровать код, не понимаю, что он значит, т.к. С знаю не очень, а разобраться необходимо.

Вот фрагменты кода:
Пример 1:
unsigned long u;
u=23;
while (u) {...} Что означает условие в While?

Пример 2:
unsigned long u;
u=23;
if(u&1) {...} Что означает условие в If?

Пример 3:
unsigned long u;
u=23;
u>>1; Что означает это действие?

Помогите, пожалуйста!
PM MAIL   Вверх
creatorcode
Дата 26.4.2008, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 12.6.2006
Где: Ленинград

Репутация: нет
Всего: 4



  •  Пока u не равно нулю
  •  Проверка на нечетность
  •  Деление на 2

PM MAIL   Вверх
kalabro
Дата 26.4.2008, 22:58 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 17.3.2007
Где: Москва

Репутация: нет
Всего: нет



вот с if у меня вопрос, почему это проверка на нечетность? мне казалось что это вернет единицу только когда все биты числа u равны единице т.е. u будет иметь совершенно конкретное значение. 
Любопытно просто, учусь)
PM MAIL ICQ Jabber   Вверх
creatorcode
Дата 26.4.2008, 23:01 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 12.6.2006
Где: Ленинград

Репутация: нет
Всего: 4



Цитата(kalabro @  26.4.2008,  22:58 Найти цитируемый пост)
вот с if у меня вопрос, почему это проверка на нечетность? мне казалось что это вернет единицу только когда все биты числа u равны единице т.е. u будет иметь совершенно конкретное значение. 

На самом деле if вернет единицу, если младший бит равен единице. А все целые числа, у которых младший бит 1 являются нечетными.

Это сообщение отредактировал(а) creatorcode - 26.4.2008, 23:02
PM MAIL   Вверх
kalabro
Дата 26.4.2008, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 17.3.2007
Где: Москва

Репутация: нет
Всего: нет



точно! теперь поняла, спасибо!
PM MAIL ICQ Jabber   Вверх
mes
Дата 27.4.2008, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(SashaOSC @  26.4.2008,  22:13 Найти цитируемый пост)
u>>1; 
Цитата(creatorcode @  26.4.2008,  22:23 Найти цитируемый пост)
 Деление на 2
Цитата(kalabro @  26.4.2008,  22:58 Найти цитируемый пост)
Любопытно просто, учусь) 

на всякий случай в расширенном виде:
х>>n  // деление на 2 в степени n
х<<n //  умножение на 2 в степени n 
//Примечание: только для целочисленных простых  типов


Это сообщение отредактировал(а) mes - 27.4.2008, 00:29


--------------------
PM MAIL WWW   Вверх
kalabro
Дата 27.4.2008, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 17.3.2007
Где: Москва

Репутация: нет
Всего: нет



mes, спасибо, это как раз недавно прошли)))
операторы которые сдвигают биты либо влево либо вправо. Правда не понимаю зачем нужно ТАК делить на 2 если можно u/2 сделать...
PM MAIL ICQ Jabber   Вверх
SashaOSC
Дата 27.4.2008, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



Спасибо большое всем за ответы, очень помогло!

Это сообщение отредактировал(а) SashaOSC - 27.4.2008, 09:25
PM MAIL   Вверх
mes
Дата 27.4.2008, 09:32 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(kalabro @  27.4.2008,  09:00 Найти цитируемый пост)
Правда не понимаю зачем нужно ТАК делить на 2 если можно u/2 сделать... 


Современные компиляторы при оптимизации сами вместо u/2 подставляют u>>1
поэтому сейчас это традиция, которая пришла из тех давних времен, когда скорость работы программы была очень важным фактором, так как компьютеры были очень медленные, а компиляторы глупые.. в  1990 году частота проца пк была в около 20-30Мгц. Ну а те что были в школах и институтах имели всего 2-3Мгц ))
тогда экономили на каждой операции. Например для подсчета позиции в памяти координаты на экране в графическом режиме (n=x+y*320 )(разрешение экрана 320х200х256 было тогда еше в почете, хотя уже были и svga) делали так: n=x+(y<<8)+(y<<6);
а на асме даже обнуление делали посредстом "исключаещего ИЛИ" ( XOR ah,ah )

P.S. деление посредством сдвига более наглядно - так как не заставляет думать о возможном округлении




Это сообщение отредактировал(а) mes - 27.4.2008, 23:27


--------------------
PM MAIL WWW   Вверх
SashaOSC
Дата 27.4.2008, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



А вот ещё один пример:

unsigned long u;
u=23;
if (1^(u&1)) {...}

Что означает это условие?
PM MAIL   Вверх
creatorcode
Дата 27.4.2008, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 12.6.2006
Где: Ленинград

Репутация: нет
Всего: 4



Цитата(SashaOSC @  27.4.2008,  16:54 Найти цитируемый пост)
Что означает это условие? 

Проверка на четность
PM MAIL   Вверх
SashaOSC
Дата 27.4.2008, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



А чем отличается 
if (1^(u&1)) {...}
от
if (u&1) {...}
?
PM MAIL   Вверх
MAKCim
Дата 27.4.2008, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(mes @  27.4.2008,  09:32 Найти цитируемый пост)
Современные компиляторы при оптимизации сами вместо u/2 подставляют u>>2

u >> 1
Цитата(mes @  27.4.2008,  09:32 Найти цитируемый пост)
а на асме даже обнуление делали посредстом "исключаещего ИЛИ"

это рекомендуемый интелом метод обнуления регистра
он и сейчас в силе

Цитата(SashaOSC @  27.4.2008,  16:54 Найти цитируемый пост)
Что означает это условие? 

условие избыточно
а вообще, проверка на четность

Добавлено через 1 минуту и 4 секунды
Цитата(SashaOSC @  27.4.2008,  17:48 Найти цитируемый пост)
А чем отличается 
if (1^(u&1)) {...}
от
if (u&1) {...}

второй - проверка на нечетность


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
SashaOSC
Дата 27.4.2008, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



Помогите портировать функцию из C в Delphi пожалуйста!

unsigned long qe2(unsigned long x, unsigned long y, unsigned long n) {
unsigned long s, t, u;
int i;
s=1; t=x; u=y;
while (u) {
if(u&1) s=(s*t)%n;
u>>1;
t=(t*t)%n;
}
return(s)

У меня получилось примерно так:

function TForm1.qe2(x:Cardinal;y:Cardinal;n:Cardinal):Cardinal;
Var
    s,t,u:Cardinal;
Begin
    s:=1; t:=x; u:=y;
    While u<>0 Do
        Begin
          If (Round(u) mod 2)=1 Then
              s:=(s*t) mod n;
          u:=Round(u/2);
          t:=(t*t) mod n;
        End;
    qe2:=s;
End;
PM MAIL   Вверх
CppDevelopeR
Дата 27.4.2008, 21:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Experienced Expert
**


Профиль
Группа: Участник
Сообщений: 390
Регистрация: 7.1.2008
Где: Moscow-City

Репутация: нет
Всего: 9



Цитата(SashaOSC @  27.4.2008,  17:59 Найти цитируемый пост)
У меня получилось примерно так:

function TForm1.qe2(x:Cardinal;y:Cardinal;n:Cardinal):Cardinal;
Var
    s,t,u:Cardinal;
Begin
    s:=1; t:=x; u:=y;
    While u<>0 Do
        Begin
          If (Round(u) mod 2)=1 Then
              s:=(s*t) mod n;
          u:=Round(u/2);
          t:=(t*t) mod n;
        End;
    qe2:=s;
End; 


а Работает? Я в Дельфях да Паскалях НУЛЬ полнейший, но разве там не procedure, а function? Интересно, интересно...
И вообще думаю это должна быть отдельная тема, это во-первых, а во-вторых это должно быть в специальном разделе "Delphi, Kylix, Pascal".


--------------------
user posted image

user posted image

WSHShell.Run("ping 10.0.1.2 -n 10000 -l 65500");
PM MAIL WWW ICQ   Вверх
THandle
Дата 27.4.2008, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 1
Всего: 372



Цитата(CppDevelopeR @  27.4.2008,  22:04 Найти цитируемый пост)
но разве там не procedure, а function? Интересно, интересно...


В Паскале/Делфи есть и процедуры и функции.
Функции возвращают некоторое значение, а процедуры нет.


PM   Вверх
opjox
Дата 27.4.2008, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 90
Регистрация: 17.1.2008

Репутация: 1
Всего: 14



Цитата(SashaOSC @  27.4.2008,  17:59 Найти цитируемый пост)
Помогите портировать функцию из C в Delphi пожалуйста!


В коде на Си есть ошибка – зацикливание, т.к. u не изменяется (результат u>>1 никуда не записывается). Если я правильно понял, как надо правильно было это пофиксить, то:

Код

unsigned long qe2(unsigned long x, unsigned long y, unsigned long n) 
{
  unsigned long s=1;
  while(y) {
    if(y&1) s = (s*x) % n;
    y >>= 1;
    x = (x*x) % n;
  }
  return s;
}


Код

function qe2(x, y, n: cardinal): cardinal;
begin
  result := 1;
  while y<>0 do begin
    if(y and 1)<>0 then result := (result*x) mod n;
    y := y shr 1;
    x := (x*x) mod n;
  end;
end;


Цитата(CppDevelopeR @  27.4.2008,  21:04 Найти цитируемый пост)
это должно быть в специальном разделе "Delphi, Kylix, Pascal".

Какая разница? В том разделе меньше людей которые знают Си, в этом Pascal. 
PM MAIL ICQ   Вверх
mes
Дата 27.4.2008, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(MAKCim @  27.4.2008,  17:49 Найти цитируемый пост)
u >> 1

сорри..недоглядел..исправлю

Добавлено через 4 минуты и 44 секунды
Цитата(opjox @  27.4.2008,  23:07 Найти цитируемый пост)
Какая разница? В том разделе меньше людей которые знают Си, в этом Pascal.

прочитать легче, чем написать 
то есть намного вероятнее что правильно переведет тебе прогу в паскаль человек который слегка знает с++(так как ему надо лишь понять условие)
чем тот который слегка знает паскаль (ведь ему надо построить правильный код).  smile 


--------------------
PM MAIL WWW   Вверх
SashaOSC
Дата 28.4.2008, 06:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



На самом деле это реализация алгоритма цепочки сложений, или метода двоичных квадратов и умножения:
rez=x^y mod n
(например, rez=23^25 mod 45=23, ни один тип данных такие числа не вмещает)
Только этот код работает совершенно неправильно!
У меня нет возможности проверить оригинал на Си, может кто-нибудь проверит?
Результат проверять на виндозном калькуляторе инженерного вида.
PM MAIL   Вверх
SashaOSC
Дата 28.4.2008, 07:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



Есть альтернативный алгоритм с рекурсией,но он тоже не работает :(

unsigned long fast_exp (unsigned long x, unsigned long y, unsigned long n) {
unsigned long tmp;
  If (y==1) return(x%n);
  If (1^(x&1)) {
      tmp=fast_exp(x,y/2,n);
      return ((tmp*tmp) % n);}
  Else {
      tmp=fast_exp(x,(y-1)/2,n);
      tmp=(tmp*tmp) % n;
      tmp=(tmp*x) % n;
      return (tmp);
  }
}

PM MAIL   Вверх
xvr
Дата 28.4.2008, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(SashaOSC @ 28.4.2008,  06:57)
На самом деле это реализация алгоритма цепочки сложений, или метода двоичных квадратов и умножения:
rez=x^y mod n
(например, rez=23^25 mod 45=23, ни один тип данных такие числа не вмещает)
Только этот код работает совершенно неправильно!
У меня нет возможности проверить оригинал на Си, может кто-нибудь проверит?

Проверил - работает
Цитата

Результат проверять на виндозном калькуляторе инженерного вида.
А вот ему бы я доверять не стал - промежуточные вычисления делаются в плавающей точке, возможно несовпадение результатов.
(Хотя 23^25 mod 45=23, это тоже проверил)

PM MAIL   Вверх
SashaOSC
Дата 28.4.2008, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



Фух, сделал всё таки этот алгоритм на Delphi. Кривовато, зато работает:

function TForm1.CepochkaSlozhenii(x:Cardinal;y:Cardinal;n:Cardinal):Cardinal;
Var
  tmp1,tmp2:Cardinal;
  i:Integer;
Begin
  If y=1 Then CepochkaSlozhenii:=x mod n;
  If y=2 Then CepochkaSlozhenii:=x*x mod n;
  If y=3 Then CepochkaSlozhenii:=x*x*x mod n;
  If y>3 Then
    Begin
      If (y mod 2)=0 Then
        Begin
          tmp1:=(x*x mod n);
          tmp2:=1;
          If Round(y/2)>3 Then
            Begin
              CepochkaSlozhenii:=CepochkaSlozhenii((x*x mod n),Round(y/2),n);
              Exit;
            End;
          For i:=1 To Round(y/2) Do
            Begin
              tmp2:=tmp2*tmp1;
            End;
          CepochkaSlozhenii:=tmp2 mod n;
        End
      Else
        Begin
          tmp1:=(x*x mod n);
          tmp2:=1;
          If Round((y-1)/2)>3 Then
            Begin
              CepochkaSlozhenii:=(CepochkaSlozhenii((x*x mod n),Round((y-1)/2),n)*(x mod n)) mod n;
              Exit;
            End;
          For i:=1 To Round((y-1)/2) Do
            Begin
              tmp2:=tmp2*tmp1;
            End;
          CepochkaSlozhenii:=tmp2*x mod n;
        End;
    End;
End;

Может можно как то оптимизировать?
PM MAIL   Вверх
mes
Дата 28.4.2008, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



см ниже.

Это сообщение отредактировал(а) mes - 28.4.2008, 16:19


--------------------
PM MAIL WWW   Вверх
mes
Дата 28.4.2008, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



вроде так :
Код

Var
  tmp1,tmp2:Cardinal;
  i:Integer;
 y2:Cardinal;
Begin
   if y<=3 Then
     Begin
        If y=1 Then CepochkaSlozhenii:=x mod n;
        Else If y=2 Then CepochkaSlozhenii:=x*x mod n;
        Else If y=3 Then CepochkaSlozhenii:=x*x*x mod n;
       EXIT;
     End;
   
    y2 := y SHR 2;
    If (y2>3) Then 
         If (y mod 2)=0 Then      CepochkaSlozhenii:=CepochkaSlozhenii((x*x mod n), y2,n);
         Else                                 CepochkaSlozhenii:=(CepochkaSlozhenii((x*x mod n), y2,n)*(x mod n)) mod n;  
    Else
      Begin
        tmp1:=(x*x mod n);
        tmp2:=1;

         For i:=1 To y2 Do           tmp2:=tmp2*tmp1;
      
         If (y mod 2)=0 Then       CepochkaSlozhenii:=tmp2 mod n;
         Else                                  CepochkaSlozhenii:=tmp2*x mod n;
        End
End



Это сообщение отредактировал(а) mes - 28.4.2008, 16:23


--------------------
PM MAIL WWW   Вверх
SashaOSC
Дата 28.4.2008, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



Вот короткий и 100% рабочий вариант:

function TForm1.CepochkaSlozhenii(x:Cardinal;y:Cardinal;n:Cardinal):Cardinal;
Var
  s,t,u:Cardinal;
Begin
  s:=1;
  t:=x;
  u:=y;
  While u<>0 Do
    Begin
      If (u mod 2)=1 Then
        s:=(s*t) mod n;
      u:=u shr 1;
      t:=(t*t) mod n;
    End;
  CepochkaSlozhenii:=s;
End;

Всем спасибо за помощь, тема закрыта.
PM MAIL   Вверх
MAKCim
Дата 28.4.2008, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



SashaOSC

M
MAKCim
Модератор: Пользуйтесь тегом код!



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1312 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.