Страницы: 1 2 вся ветка
Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.22;
Скачать: [xml.tar.bz2];




Вниз

Pascal срочно, плзззз... 


cok   (2002-03-30 14:55) [0]

Я сейчас пишу прогу на Паскале, вот. Проблева в следующем:
у меня есть число в 10-ной системе счисления, я перевожу его в 2-ую сист.сч., меняю местами некоторые 1 и 0, а потом перевожу это в 10-ую сист.сч, но число больше 6000, и поэтому, когда я его перевожу в 2-ую сист. по длине оно будет ого го, т.е длиннее чем LongInt! Я пытался использовать тип comp или extended, но тогда прога не правильно будет переводить число в 10-ую сист. сч. Че делать?



Anatoly Podgoretsky   (2002-03-30 14:58) [1]

С какой стати у числа изменится размер от замены 0-1.
Паскаль правильно переводит и в comp и в extended, у тебя где то ошибка.
"Че делать?!" - быть конкретнее, без подземного стука.



drpass   (2002-03-30 15:46) [2]

Видишь ли, компьютер все числа хранит в двоичной системе, а десятичная, шестнадцатеричная и т.д. - это всего лишь формат ввода/вывода. Если тебе хочется поменять несколько битов, ничего никуда не нужно переводить



cok   (2002-03-30 19:36) [3]

>Anatoly Podgoretsky © (30.03.02 14:58)
>С какой стати у числа изменится размер от замены 0-1.
Размер у числа изменится, если я его из 10-ной сист.сч. переведу в 2-ую. Например, 11=1011, (цифр в два раза больше стало!)



Fay   (2002-03-31 05:12) [4]

2cok
Не надо Вам так отвечать Anatoly Podgoretsky. Это уважаемый мастер.
Вопрос Ваш приведённой формулировке - полный бред (так мне кажется). Пожалуйста, уточните.



Anatoly Podgoretsky   (2002-03-31 10:19) [5]

Так ты про текст, а чего тогда приплел LongInt, да еще и comp вместе с extended.
Кажетмя полное непонимание, не мешало бы повнятнее.
Что такое числа и какие у них ограничения можешь посмотреть в хелпе по теме "About types" если тебе это поможет, очень уж запущено.

Fay © (31.03.02 05:12)
Как видишь не очень :-)



Rooman   (2002-03-31 10:53) [6]

Кранты! Мастера как дети отвечать стали! Куда мир катится!
Ответ на вопрос: чтобы поменять биты в числе совершенно не надо его ни во что конвертировать. Делаешь так:

var i:longint;

...
i:=6000;
...
//изменение нулевого бита на противоположный:
i:=i xor 1;
//обнуление нулевого бита:
i:=i and not 1;
//присвоение нулевому биту единицы:
i:=i or 1;

//тоже самое для пятого бита, к примеру
//изменение пятого бита на противоположный:
i:=i xor 32;
//обнуление пятого бита:
i:=i and not 32;
//присвоение пятому биту единицы:
i:=i or 32;

Число, которое будет у тебя вместо 1 или 32 вычисляется по формуле: число = 2 в степени номер_бита;





dymka   (2002-03-31 10:54) [7]

Как уже сказал drpass, переводить для смены бит ничего не нужно... Существует такое понятие как битовые операции...
Это not, or, and, xor, shr итп... Поизучив их внимательнее, ты вероятно сможешь найти решение...
Второе - раз уж ты вздумал перевести десятичное число в двоичное, то количество цифр будет определятся логарифмом по основанию 2 плюс единица... поэтому нетрудно заметить, что число 6000 займет log2(6000) + 1 = 13.6 т.е. 13 разрядов...
Поэтому проще использовать строку для двоичного представления числа, кстати обмен битами в этом случае будет намного проще...



dymka   (2002-03-31 10:56) [8]

2Rooman - он похоже не биты инвертировать собрался, а менять местами - тобишь пятый бит поставить на первое место, ну а первый на пятое...



Anatoly Podgoretsky   (2002-03-31 11:08) [9]

Rooman © (31.03.02 10:53)
Так у него проблема с

"но число больше 6000, и поэтому, когда я его перевожу в 2-ую сист. по длине оно будет ого го, т.е длиннее чем LongInt!"



Rooman   (2002-03-31 11:11) [10]

2dymka - булева алгебра нужна здесь для понимания сути. Алгоритм, основаный на булевой алгебре, работает много эффективнее, чем возиться со строками, имхо:)

Обмен битами можно сделать так:

Например, меняем нулевой и первый биты местами:

var i,j,k:longint;
...
i:=254;
//обмен 0 и 1 битов местами
j:=i and 1;//выделили нулевой бит
k:=i and 2;//выделили первый бит
if k>0 then i:=i or 1 else i:=i and not 1;
if j>0 then i:=i or 2 else i:=i and not 2;



Song   (2002-03-31 11:13) [11]

Если нужно написать операцию перевода bin <--> dec таким корявым алгоритмом, то нужно эти разряды которые после перевода "будут больше чем убирается в LongInt" надо хранить только в ShortString, а уж никак не в Int переменных.



dymka   (2002-03-31 11:24) [12]

2Rooman - а никто и не спорит... :).
Но вдруг ему захочется все-таки перевести в двоичную строку :)
меняем i и j бит местами:


var
TempChar: char;
...
TempChar := BitStr[i];
BitStr[i] := BitStr[j];
BitStr[j] := TempChar;

Ну здесь еще такая фишка - нулевой бит это первый символ :)



Rooman   (2002-03-31 11:28) [13]

Короче, дело к ночи:)
Вот вам функция, которая меняет два любых бита в числе:

procedure swapbits(BitPos1,BitPos2:byte;var Number:longint);
var i1,i2,j,k:longint;
begin
i1:=1;
i2:=i1;
i1:=i1 shl BitPos1;
i2:=i2 shl BitPos2;
j:=Number and i1;
k:=Number and i2;
Number:=Number or i2 or i1;
if j=0 then Number:=Number xor i2;
if k=0 then Number:=Number xor i1;
end;



Rooman   (2002-03-31 11:30) [14]

P.S. меняет местами! Позиции битов нумеруются от 0 до 31!



dymka   (2002-03-31 11:33) [15]

ес чо, то допустима такая конструкция

i1 := 1 shl BitPos1;
i2 := 1 shl BitPos2;



Rooman   (2002-03-31 11:35) [16]

согласен:)



Rooman   (2002-03-31 11:37) [17]

2dymka - только в твоем варианте код компилируется неоптимально, хотя в данном случае это не критично.



Rooman   (2002-03-31 12:08) [18]

А вот более оптимальный вариант той-же функции:

procedure swapbits(BitPos1,BitPos2:byte;var Number:longint);
var i1,i2,m:longint;tmp:byte;
begin
if BitPos1>BitPos2 then
begin
tmp:=BitPos1;
BitPos1:=BitPos2;
BitPos2:=tmp;
end;
i1:=1;
i2:=i1;
i1:=i1 shl BitPos1;
i2:=i2 shl BitPos2;
m:=BitPos2-BitPos1;
Number:=(Number and not(i1 or i2))xor (((Number and i1) shl m)xor((Number and i2) shr m));
end;



cok   (2002-03-31 15:03) [19]

Простите, если невнятно объяснил суть задачи.
Приведу полный ее текст:
Дано целое десятичное число N (1<=N<=65535). Некто записал это число в двоичном формате и стал циклически сдвигать вправо, затем брать последнюю цифру числа и переносить ее в начало. Например, если N=11, то в 2-ом формате это 1011. После 1-го сдвига получим 1101, после 2-го - 1110, после 3-го 0111, после 4-го - исходное число 1011. Видно, что максимальное значение из всех полученных имеет число 1110, и это значение завно 14.
Требуется создать прогу, по которой для заданного числа N определяется максимальное значение числа, которое получится в результате вышеописанных сдвигов.



Anatoly Podgoretsky   (2002-03-31 15:19) [20]

И всего то?

max := N;
for i := 1 to 16 do begin
F := N and 1;
M := N shr 1;
if F = 1 then N or $8000;
if N > Max then Max := N;
end;



Rooman   (2002-03-31 15:53) [21]

интересно, где такою задачу применить можно?



JibSkeart   (2002-03-31 15:56) [22]

65535 = FFFF = 16bit ??
255 = FF = 8bit ??
Нет а что незя использовать массив ??
помойму проше ...
(То есть переводишь в двоичный .. 0 и 1 бросаешь в массив
по порядку как есть :)
а сдвигать байты мона и в массиве сразу ..
)

я тут пример для 8 бит набросал перевода из битов в десятичное число
Program Test;
Uses
Crt;
Type
t=Array [0..7] of Byte; {or [0..31] !!! }
t1=^t;
Var
x:Word;
s:T1;
begin
ClrScr;
New(s);
s^[0]:=1; s^[1]:=0; s^[2]:=0; s^[3]:=0; s^[4]:=1; s^[5]:=0; s^[6]:=0;
s^[7]:=0; {10010b=34d}
asm
xor bx,bx
les di,[s]
mov al,[es:di]
shl al,1
add bl,al
mov al,[es:di+1]
shl al,2
add bl,al
mov al,[es:di+2]
shl al,3
add bl,al
mov al,[es:di+3]
shl al,4
add bl,al
mov al,[es:di+4]
shl al,5
add bl,al
mov al,[es:di+5]
shl al,6
add bl,al
mov al,[es:di+6]
shl al,7
add bl,al
mov al,[es:di+7]
shl al,8
add bl,al
{ ... }
mov x,bx
end;

Writeln(x);
Dispose(s);
end.

А вообше сдеся Вам инфы сказали люди предостаточно ...

Да и Помоему на Асме есть та функция которая передвигает биты (в лево и в право)причем с переносом битов (если я не ошибаюсь)



JibSkeart   (2002-03-31 16:06) [23]

Да а нужно ли все енти переводы оттуда туда
всмысле из десятичной в двоичную и ....



Rooman   (2002-03-31 16:14) [24]

в ассемблере есть инструкции

ROR register,count - циклическое вращение вправо
ROL register,count - циклическое вращение влево

в связи с этим код Анатолия Подгорецкого упрощается:

var NNN:word;
...
asm
mov ax,NNN
mov dx,ax
mov cx,16
@1:
ror dx,1
cmp ax,dx
jb @2
mov ax,dx
@2:
loop @1
mov NNN,ax
end;

коротко и быстро!



JibSkeart   (2002-03-31 16:32) [25]

Rooman ©
Угу точно
Ну немного опередил меня ... :))



Anatoly Podgoretsky   (2002-03-31 17:16) [26]

Rooman © (31.03.02 16:14)
Я не был уверен, что допустимы асм коды, но могу поправить код, а то он с ошибкой, не учитывается 32 битная математика.
Во первых превратив его в функцию

function MaxCombo(N: Word) : Word;
asm
mov dx,ax
mov ecx,16
@1:
ror dx,1
cmp ax,dx
jb @2
mov ax,dx
@2:
loop @1
end;



Rooman   (2002-03-31 18:23) [27]

да, Анатолий, ecx не заметил... опечаточка вышла...



Rooman   (2002-03-31 18:25) [28]

Вот на все бы вопросы такие ответы были - красота! :)))



Anatoly Podgoretsky   (2002-03-31 19:06) [29]

Вот если бы не приходилось вытягивать, что именно нужно, была бы красота



JibSkeart   (2002-03-31 19:36) [30]

Вопервых если он пишет на паскале под досем ...
то сакс
он не поддерживает 32-х битные регистры .. :((
можно но только на TASMe или MASME написать и в OBJ
а потом оттуда ... но енто ...

function MaxCombo(N: Word) : Word;assembler еще одна поправка
asm
mov dx,ax
mov ecx,16 --- есх 32-х битный да и зачем ?? ты все рано значение для шетчика пихаеш 16 а может быть 32 ??
@1:
ror dx,1
cmp ax,dx
jb @2
mov ax,dx
@2:
loop @1
end;

да и к томуже по его словам
N (1<=N<=65535).

и не нужна 32 битная математика .65535= 16 бит



Anatoly Podgoretsky   (2002-03-31 19:55) [31]

Ты видимо не представляешь как работает команда loop в 32 битном компиляторе, так вот она учитывает не только cx, но и e.
К тому же ты путаешь 32 битный счетчик с 16 битными рабочими регистрами ax, dx

Во вторых по твоим словам в старом турбо паскале нельзя использовать асмь команды, только TASM или MASM, это не так, начиная с версии 6, можно напрямую, а до этого inline
вот в 16 разрядном компиляторе, конечно нужно mov cx,16



JibSkeart   (2002-03-31 20:05) [32]

насчет ecx 32 я мог ошибится так как с 32-х битным счетчиком
я не сталкивался (не приходилось)

//Во вторых по твоим словам в старом турбо паскале нельзя использовать асмь команды, только TASM или MASM, это не так, начиная с версии 6, можно напрямую, а до этого inline

про Tasm, Masm я имелл виду то что так можно работать с 32 бит рег.

но не имелл ввиду то что паскаль не знает асма
А с 32б мона работать и через db константы ...
на пискале (досявом)



Rooman   (2002-03-31 20:25) [33]

Уже начиная с 386 процессора LOOP оперирует с 32-разрядным счетчиком:)



Anatoly Podgoretsky   (2002-03-31 20:27) [34]

Ну ок уточнили.



Anatoly Podgoretsky   (2002-03-31 20:44) [35]

может и 16 и 32 зависит от префикса, но это не касается Дельфи, только 32



cok   (2002-03-31 21:49) [36]

>Anatoly Podgoretsky © (31.03.02 15:19)
>max := N;
>for i := 1 to 16 do begin
> F := N and 1;
> M := N shr 1;
> if F = 1 then N or $8000;
> if N > Max then Max := N;
>end;


> M := N shr 1; Здесь, наверно, надо написать N:=N shr 1;
> if F = 1 then N or $8000; Здесь ошибка, но не пойму какая.







cok   (2002-03-31 21:51) [37]

>JibSkeart © (31.03.02 19:36)
Твой код работает неверно!



Anatoly Podgoretsky   (2002-03-31 22:11) [38]

У сеня что буква М, конечно исправь
И здесь конечно, код писался быстро

if F = 1 then N := N or $8000;

Мог бы догадаться



cok   (2002-04-01 14:22) [39]

2 Anatoly Podgoretsky ©
Я так и догадался, но все равно работает НЕВЕРНО.



Alx2   (2002-04-01 14:57) [40]

Вот вариант на "чистом" ObjectPascal:

Function rormax(Val: Word): Word;
Var
K, HigherBitPos, LowBit: Integer;
Begin
Result := Val;
If Val = 0 Then exit;
HigherBitPos := trunc(ln(Val) / ln(2));
For K := 0 To HigherBitPos Do
Begin
LowBit := Val And 1;
Val := (Val Shr 1) Or (LowBit Shl HigherBitPos);
If Val > Result Then Result := Val;
End;
End;



cok   (2002-04-01 20:07) [41]

2 Alx2 © (01.04.02 14:57)
Большое вам спасибо! Ваш код работает верно.



KSergey   (2002-04-08 10:27) [42]

А вообще это классно получается: дают человеку задачку (в некоем учебном заведении), он бросает ее в форум, на ответ говорит "а он неверен, сделайте чтоб работало!" после чего дожидается правильного решения, сдает его - ну и молодец короче. И это еще учитывая то, что задачи во всех учебных заведениях даются с расчетом на уровень троечника.
Далеко пойдешь, cok!
Хочется матом, да воспитание не позволяет.

PS: хотя обсуждение получилось весьма интересным, надо заметить.



Rooman   (2002-04-08 11:36) [43]

Выводов из всего этого четыре:

1. В уч.завед. у нас преподы не знакомы с Дельфи;
2. В наших уч.завед. учат тому, что было известно 20 лет назад, а сейчас нигде не нужно (не используется);
3. Многие не знакомы с понятием "оптимизация кода процессора";
4. Коммунизм жив!
:)))

П.С. А кстати, собственно, на чем основывается утверждение о неработоспособности кода Анатолия? У меня вот все верно работает:)



Alx2   (2002-04-08 12:00) [44]

>Rooman © (08.04.02 11:36)
>утверждение о неработоспособности кода Анатолия?
"Вращать" число надо в пределах его битовой длины, а не регистра.
>Многие не знакомы с понятием "оптимизация кода процессора";
Нет достаточных оснований для такого высказывания. Хотя, если брать в соответствующих масштабах, то - пожалуй.
Но лабы оптимизировать под процессор обычно не требуется, если не оговорено другое.



Rooman   (2002-04-08 12:21) [45]

ага, погорячился с вышесказанным...
действительно, в задаче имеется ввиду вращение числа нефиксированой ширины... такое в практике нечасто встречается:)

ну хорошо, тогда так:

function rotateN(N:word):word;
var mask:word;
begin
if N=0 then exit;
mask:=$8000;
while (mask and N)=0 do mask:=mask shr 1;
result:=N;
while mask>0 do
begin
asm
xor ax,ax
rcr N,1
jnc @1
mov ax,N
or ax,mask
mov N,ax
@1: shr mask,1
end;
if N>result then result:=N;
end;
end;



Rooman   (2002-04-08 12:23) [46]

result:=N надо первой строчкой ф-ии поставить (а не четвертой)



Rooman   (2002-04-08 12:40) [47]

А вот полностью на асме:

function rotatemaxN(N:word):word;
asm
and ax,ax
jz @4
mov cx,$8000
@1:
test ax,cx
jnz @2
shr cx,1
jmp @1
@2:
shr ax,1
jnc @3
or ax,cx
@3:
shr cx,1
jnz @2
@4:
end;

И не нужно логарифмов:)



Alx2   (2002-04-08 12:42) [48]

>Rooman © (08.04.02 12:23)
:))
Что, ж продолжим флейм.
rotateN(11)=13. А надо 14 :P



Rooman   (2002-04-08 12:48) [49]

Блин, ошибку прозевал. Вот исправленый код:

function rotatemaxN(N:word):word;
asm
and ax,ax
jz @5
mov cx,$8000
mov dx,ax
@1:
test ax,cx
jnz @2
shr cx,1
jmp @1
@2:
shr dx,1
jnc @3
or dx,cx
@3:
cmp ax,dx
jae @4
mov ax,dx
@4:
shr cx,1
jnz @2
@5:
end;



Rooman   (2002-04-08 12:59) [50]

Торможу и не бибикаю:))) Саму маску нельзя сдвигать:)

Вот так правильно (вроде окончательно):

function rotatemaxN(N:word):word;
asm
and ax,ax
jz @5
mov cx,$8000
mov dx,ax
@1:
mov bx,cx
test ax,cx
jnz @2
shr cx,1
jmp @1
@2:
shr dx,1
jnc @3
or dx,cx
@3:
cmp ax,dx
jae @4
mov ax,dx
@4:
shr bx,1
jnz @2
@5:
end;


и на Паскале:

function rotateN(N:word):word;
var mask,tmp:word;
begin
if N=0 then exit;
mask:=$8000;
while (mask and N)=0 do mask:=mask shr 1;
result:=N;
tmp:=mask;
while tmp>0 do
begin
asm
xor ax,ax
rcr N,1
jnc @1
mov ax,N
or ax,mask
mov N,ax
@1: shr tmp,1
end;
if N>result then result:=N;
end;
end;



Alx2   (2002-04-08 13:00) [51]

Издеваешься?
rotatemaxN(11)=13. А надо 14 :P



Rooman   (2002-04-08 13:01) [52]


> Alx2 © (08.04.02 13:00)
> Издеваешься?
> rotatemaxN(11)=13. А надо 14 :P


см. последний ответ - он верный. (Rooman © (08.04.02 12:59))



[MC]NuClon   (2002-04-08 13:04) [53]

хаха... Смотрю и удивляюсь... Из таких тривиальных тем получаются такие страсти... хыы. Конечно, кто-то прав, кто-то нет.
Кто-то сказал, мол, где это может применяться? А вы, уважаемый, когда-нибудь слышали про олимпиады??? И вообще задача на простой тривиальный перебор, но можно решить применив побольше мозгов, получив при этом более рациональный алгоритм.
Ходите к нам http://forum.isurgut.ru/cgi-bin/ultimatebb.cgi?ubb=forum&f=17
создайте нам атмосферу спора как тут.
http://nuclon.stsland.ru



Rooman   (2002-04-08 13:12) [54]

Да и еще, если компилить АСМ-код в дельфи, то надо в начале функции поставить pusha, а в конце - popa. То есть:

function rotatemaxN(N:word):word;
asm
pusha
and ax,ax
jz @5
mov cx,$8000
mov dx,ax
@1:
mov bx,cx
test ax,cx
jnz @2
shr cx,1
jmp @1
@2:
shr dx,1
jnc @3
or dx,cx
@3:
cmp ax,dx
jae @4
mov ax,dx
@4:
shr bx,1
jnz @2
@5:
popa
end;



Rooman   (2002-04-08 13:14) [55]

Блин, устал свои же ошибки править уже:)))
Если компилить АСМ-код в дельфи, то надо в начале функции поставить push ebx, а в конце - pop ebx. То есть:

function rotatemaxN(N:word):word;
asm
push ebx
and ax,ax
jz @5
mov cx,$8000
mov dx,ax
@1:
mov bx,cx
test ax,cx
jnz @2
shr cx,1
jmp @1
@2:
shr dx,1
jnc @3
or dx,cx
@3:
cmp ax,dx
jae @4
mov ax,dx
@4:
shr bx,1
jnz @2
@5:
pop ebx
end;



Rooman   (2002-04-08 13:18) [56]

Вот. теперь точно все. Задача решена. Осталось оптимизировать с учетом закономерностей:)



cok   (2002-04-08 20:01) [57]

2 KSergey © (08.04.02 10:27)
ЭТО ЗАДАНИЕ НЕ ДЛЯ ТРОЕШНИКОВ!!!!!!!!!! Поверьте мне (я просто не хочу говорить откуда оно, но не из школы и даже близко не от туда!)



[MC]NuClon   (2002-04-08 20:35) [58]

Задание пусть и не для троешников, но оно простое...
Хотите лучше?
Вас ждут тут: informatics.ru



Yaro   (2002-04-08 20:43) [59]

.



cok   (2002-04-08 21:06) [60]

2 [MC]NuClon (08.04.02 20:35)
Если бы оно было такое простое, то наверное все бы решили его верно с 1-го раза, но этого что-то не наблюдалось (за редким исключением)



[MC]NuClon   (2002-04-08 21:20) [61]

Сравни с http://informatics.ru/roi/XIII/firstround.xml
А мы ведь это решали.



cok   (2002-04-09 18:09) [62]

Эта ветка побьет все рекорды :)




Страницы: 1 2 вся ветка
Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.22;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.85 MB
Время: 0.043 c
1-69852           Sergey Saf            2002-04-06 21:13  2002.04.22  
Комбинация кнопок


1-69773           VJar                  2002-04-10 00:42  2002.04.22  
Небольшой почтовый проект


3-69715           Макс                  2002-03-06 11:14  2002.04.22  
Запьсь JPEG в поле типа Image


3-69702           don1780               2002-03-29 04:13  2002.04.22  
Уважаемые, помогите начинающему!


1-69846           f0rm                  2002-04-08 22:59  2002.04.22  
Регистрация собственного расширения