On-line: PSP, tnsr2, гостей 1. Всего: 3 [подробнее..]
АвторСообщение



Пост N: 26
Зарегистрирован: 07.08.06
ссылка на сообщение  Отправлено: 12.10.06 02:59. Заголовок: Битовый сдвиг чисел в клиппере. Это возможно или нет ?


Hi all.
Кто-нибудь знает, есть ли в штатных средствах клиппера возможность выполнить над числом битовый сдвиг на N разрядов вправо/влево ? (т.е. не делить/умножать на степень числа 2, а именно СДВИНУТЬ биты исходного числа и получить результат, как в АСМе SHR/SHL)

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 24 , стр: 1 2 All [только новые]


постоянный участник


Пост N: 4
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 12.10.06 09:04. Заголовок: Re:


В штатных средствах клиппера возможности работы с битами нет, есть в xHarbour.
Но есть возможность или использовать библиотеки сt, nanfor
или написать самомому на что-то С/ASM и подключить к Clipper с помощью extend.api/extasm.inc.



Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 217
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 12.10.06 13:12. Заголовок: Re:


Есть внутренние функции Clipper, точнее скорей всего это функции Microsoft C, на котором написан Clipper, которые выполняют сдвиг вправо и влево (какой-то из них по-моему арифметический сдвиг, то есть с учетом знака числа). То есть надо всего лишь написать функцию, которая принимает один параметр в ренистры AX:DX (в Clipper целые числа хранятся в виде двух слов) и передать их на вход этой внутренней функции, а затем вернуть результат.
Параметр можно принять (если писать на ассемблере) с помощью функции __lparam. Например

mov ax,1
call __lparam,ax ; DX:AX - target value

Затем вызвать внутреннюю функцию Clipper (Microsoft С), передав ей значения в регистрах DX:AX. А затем вернуть значение с помощью функции __retnl

call __retnl,ax,dx
ret

Вот и вся программа!


Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 38
Зарегистрирован: 06.06.06
ссылка на сообщение  Отправлено: 12.10.06 16:31. Заголовок: Re:


Есть в Clipper Tools функция:
NUMROL() - Выполняет циклический сдвиг 16-битового слова.

Описание

Функция позволяет осуществить циклический сдвиг влево битов
16-битового слова с числовым значением в диапазоне от 0 до 65535.

При сдвиге бит, выходящий за разрядную сетку слева, переносится в
самый правый разряд. Параметр <lLowByte> позволяет задать сдвиг только
младшего байта слова.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 219
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 12.10.06 16:56. Заголовок: Re:


ort пишет:

 цитата:
Есть в Clipper Tools функция:
NUMROL() - Выполняет циклический сдвиг 16-битового слова.


Строго говоря, получается, что это не операция сдвига над числом Clipper-а, а операция сдвига над "получислом" Clipper-а.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 27
Зарегистрирован: 07.08.06
ссылка на сообщение  Отправлено: 12.10.06 23:23. Заголовок: Re:


Всем ответившим большое спасибо.
Правда, странно как-то получилось:
1) ф-ция циклич сдвига ВЛЕВО в clipper tools есть, а ВПРАВО - почему-то нет. А мне как раз нужна последняя (означающая деление на 2 в степени N)
2) простой тест показал, что ф-ция NUMROL() работает МЕДЛЕННЕЕ, чем обычное умножение на 2 (200000 итераций выполнялось соотв-но 1.67" и 1.34"). Хотя я неоднократно слышал/читал, что бравые Си`шники и АСМ`еры никогда не умножают и не делят на число, равное степени 2 -- юзают вместо этого именно SHL/SHR. А в клиппере всё оказалось наоборот: надо забыть про эту идею и просто умножать/делить "как в школе учили", без извращений. Кто-нить может объяснить этот эффект ?


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 326
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 13.10.06 08:46. Заголовок: Re:


Понравилось

p519446 пишет:

 цитата:
Хотя я неоднократно слышал/читал, что бравые Си`шники и АСМ`еры никогда не умножают и не делят на число, равное степени 2 -- юзают вместо этого именно SHL/SHR.



Настоящие програмисты пишут только в машинном коде :)

А компилятор сам должан оптимизировать такие операции

#include "extend.h"

CLIPPER BitShiftR()
{
_retnl(_parnl(1) >> _parni(2));
}

CLIPPER BitShiftL()
{
_retnl(_parnl(1) << _parni(2));
}

Не проверял, но должно работать :)


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 327
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 13.10.06 08:53. Заголовок: Re:


Если есть проблемы со сборкой - давай адрес, отправлю готовый obj

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 9
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 13.10.06 10:41. Заголовок: Re:



p519446 пишет:

 цитата:
ф-ция циклич сдвига ВЛЕВО в clipper tools есть, а ВПРАВО - почему-то нет



Описание NUMROL() в сt2rus.ng

Выполняет циклический сдвиг 16-битового слова.
------------------------------------------------------------------------------

Синтаксис

NUMROL(<nWORD1|cHexWORD1>, <nWORD2|cHexWORD2>,
[<lLowByte>]) --> nWORD

Параметры

<nWORD1|cHexWORD1> - сдвигаемое значение в диапазоне от 0 до 65535,
задаваемое в виде десятичного числа или символьной строки
шестнадцатеричных цифр.

<nWORD2|cHexWORD2> - количество производимых сдвигов влево, задаваемое
в виде десятичного числа или символьной строки шестнадцатеричных цифр.

<lLowByte> - необязательный логический параметр, задающий при значении
.T. сдвиг младшего байта (диапазон количества сдвигов от 1 до 7), а
при значении .F. или по умолчанию сдвиг всех 16 битов слова (диапазон
количества сдвигов от 1 до 15).

Возвращаемое значение

nWORD - числовое значение слова с циклически сдвинутыми битами.

Описание

Функция позволяет осуществить циклический сдвиг влево битов
16-битового слова с числовым значением в диапазоне от 0 до 65535.

При сдвиге бит, выходящий за разрядную сетку слева, переносится в
самый правый разряд. Параметр <lLowByte> позволяет задать сдвиг только
младшего байта слова.

Примечания

 Количество сдвигов вычисляется как остаток от деления значения,
заданного параметром <nWORD2|cHexWORD2>, на число 16 при значении .F.,
или на число 8 при значении .T. параметра <lLowByte> (длина слова и
байта соответственно).

Для выполнения циклического сдвига вправо на 1 бит следует
выполнить циклический сдвиг (влево) на 15 для слова или на 7 для
байта, а для сдвига вправо на 2 бита - на 14 и 6 соответственно, и
т.д.


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 220
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 13.10.06 11:35. Заголовок: Re:


Вот внутрення Clipper (Microsoft C) функция арифметического сдвига вправо.

;This function performs arithmetic right shifting of a DWORD
;in register pair DX:AX


PROC __aFlshr
xor ch,ch
jcxz @@20
@@10:
sar dx,1
rcr ax,1
loop @@10
@@20:
ret
ENDP __aFlshr

То есть в дополнение к тем функциям, о которых я писал, надо просто включить вызов данной функции, поместив в регистр CL число битов, на которые хотите осуществить сдвиг, а в DX:AX сдвигаемое число.

Приблизительно код (TASM 4.0) будет выглядеть следующим образом (это непроверенный код)

TITLE Арифметический сдвиг вправо. Автор: Григорьев Владимир.

IDEAL

MODEL LARGE FULLSHR_TEXT, CPP

GLOBAL __lparam: PROC
GLOBAL __aFlshr: PROC
GLOBAL __retnl: PROC

GLOBAL FullShr: PROC

CODESEG FULLSHR_TEXT

PROC FullShr
LOCAL @@nValue:DWORD
mov ax,1
call __lparam,ax
mov [word @@nValue],ax
mov [word @@nValue+WORD],dx
mov ax,2
call __lparam,2
mov cx,ax
mov ax,[word @@nValue]
mov dx,[word @@nValue+WORD]
call __aFlshr
call __retnl,ax,dx
ret
ENDP FullShr

END

Я думаю, данная фнкция должна работать быстро. Быстрее просто нет! Причем она делает арифметический сдвиг вправо "полного" целого числа Clipper.

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 43
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 13.10.06 15:18. Заголовок: Re:



 цитата:

2) простой тест показал, что ф-ция NUMROL() работает МЕДЛЕННЕЕ, чем обычное умножение на 2 (200000 итераций выполнялось соотв-но 1.67" и 1.34"). Хотя я неоднократно слышал/читал, что бравые Си`шники и АСМ`еры никогда не умножают и не делят на число, равное степени 2 -- юзают вместо этого именно SHL/SHR.

А в клиппере всё оказалось наоборот: надо забыть про эту идею и просто умножать/делить "как в школе учили", без извращений. Кто-нить может объяснить этот эффект ?




Странно требовать от языка высокого уровня высокой скорости обработки 16-битовых чисел. В Клиппер ведь вообще нет понятия "16-битовое целое" - только NUMERIC. Соотв. главное здесь - не высокая скорость обработки двоичных данных (для этого есть Си и ассемблер) - а удобство написания больших и очень больших программных проектов, быстрая работа с табличными данными и т.п.

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



Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 222
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 13.10.06 16:05. Заголовок: Re:


Как я уже сказал, моя функция FullShr( [<nNumber>], [<nCount>] ) - самя быстрая! Всю проверку на допустимость типов выполняет функция __lparam(). Более сложной проверки нет необходимости делать.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 28
Зарегистрирован: 07.08.06
ссылка на сообщение  Отправлено: 14.10.06 11:31. Заголовок: Re:


2Sergy: клиппер выясняет тип переменной и допустимость проведения операции в ОБОИХ вариантах теста, как при тупом умножении переменной на число 2, так и при вызове ф-ции NUMROL(). Получается, что либо время на проверки при использовании NUMROL(N,1) больше, чем при выполнении N*2, либо сама NUMROL выполняется медленнее. Я не собираюсь вычислять на клиппере что-то "страшное"; просто в моём коде часто выполняются операции деления на целые числа (в т.ч. на 2, 4, 8) -- вот и решил проверить, есть ли способы увеличения скорости.
BTW, замена кода A = B / C на код A = IIF(C=1,B,B/C) уменьшает время примерно на 9% (проверял 5 раз на 1 млн итераций, машина 2.4MHz: 6.10" против 5.55"). Что-то мне подсказывает, что применение сдвига вправо вместо деления на 2,4 и 8 также может дать некий плюсовой эффект.

2Pasha: если не сложно, кинь, плз, obj-файл с функцией, которой я могу задать два параметра: исходное число и количество битов, на которое надо сдвигать право.


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 334
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 14.10.06 11:46. Заголовок: Re:


Куда отправить ?


Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 44
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 14.10.06 12:09. Заголовок: Re:



 цитата:

2Sergy: клиппер выясняет тип переменной и допустимость проведения операции в ОБОИХ вариантах теста, как при тупом умножении переменной на число 2, так и при вызове ф-ции NUMROL(). Получается, что либо время на проверки при использовании NUMROL(N,1) больше, чем при выполнении N*2, либо сама NUMROL выполняется медленнее.



вся скорость, выигрываемая битовым сдвигом в NUMROL(), теряется на сохранении регистров в стеке перед вызовом внешней функции и восстановлением оных при ее завершении.


 цитата:

Я не собираюсь вычислять на клиппере что-то "страшное"; просто в моём коде часто выполняются операции деления на целые числа (в т.ч. на 2, 4, 8) -- вот и решил проверить, есть ли способы увеличения скорости.
BTW, замена кода A = B / C на код A = IIF(C=1,B,B/C) уменьшает время примерно на 9% (проверял 5 раз на 1 млн итераций, машина 2.4MHz: 6.10" против 5.55").



Время в данном тесте будет очень сильно зависеть от входного набора данных, не так-ли? Чем меньше раз вместо сложного деления будет выполнено простое присвоение, тем больше экономия.


 цитата:

Что-то мне подсказывает, что применение сдвига вправо вместо деления на 2,4 и 8 также может дать некий плюсовой эффект.



Ты занимаешься достаточно тонкой оптимизацией кода, раз пишешь ТАКИЕ вещи. Похавльно, но имей ввиду, что все твои старания могут банально сыграть в "ноль" или даже в "минус" при простой замене ЛЮБОГО компонента выполнения: как ядра (например, конвейеры в процессорах AMD работают совершенно иначе, чем в Intel), так и 16-битной машины в ОС (к выходу Vista - будь готов! ). Кроме этого, видя "застой" в средствах ДОС-разработки, авторы Blinker всё больше увлекаются всякими улучшениями - не замечаешь?

Будут ли твои оптимизации работать, к примеру, на 7 версии Блинкера, под Vista, на процессоре Core Duo ? Вот и я об этом: забей. Чем стандартнее, тем проще потом будет разбираться. IMHO.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 29
Зарегистрирован: 07.08.06
ссылка на сообщение  Отправлено: 14.10.06 14:54. Заголовок: Re:


2Pasha: мыль, плз, сюда: p519446 {сабацька} yandex.ru
2Sergy: возражений нет, ты прав. Но попробовать всё же очень хотца...
Кстати, вопрос: а что там будет в Vista ? DOS-машина умрёт окончательно или будет на что-то заменена ?

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 335
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 14.10.06 20:45. Заголовок: Re:


Отправил

Я скомпилировал эту функцию старым добрым Turbo C 2.0, выпущенныи еще в 1988г,
то еще в доисторическое время
Поскольку он вставляет вызовы своих функций: они необходимы, так как
сдвиг 32битного числа одной командой 16-разрядного процессора сделать нельзя,
линковать программу надо с библитекой cl.lib (для large модели памяти)
Я решил заодно тебе отправить и компилятор и все что надо для сборки - получилось
немногим больше 200к
Как видишь писать маленькие функции на C очень просто, собирать тоже
Надо запустить tcc.exe <prgname>.c
И в файле turboc.cfg заменить в строке -Iinc;d:\clip52\include мои каталоги
на свои
Если критична скорость вычислений, то все что можно лучше оформить в виде функций
на C, передавать параметры ординарных типов (с массивами сложнее) легко, возвращать
результат тоже
Но все это понятия из давно ушедшей эпохи

Что касается vista - как я понимаю это ОС для 32-разрядных машин
Будет ли там 16-битный эмулятор я не знаю, но это не так уж и важно
Сккажем winxp64 вышла давно, и эмулятора 16-бит там нет. Но его сделали сторонние
разработчики. Так может будет и для vista
Но все это опять таки не то
Зачем ходить на костылях если можно твердо стоять на своих двоих
Для этого есть харбор. В принципе его можно адаптировать для любой ОС, где есть
компилятор С и реализован Yacc, то есть практически везде
И для winxp64 харбор уже собран. И интеграция с С в харборе больше, чем у клиппера,
можно фрагменты кода на C вставлять прямо в prg-функцию
Надо жить в этом веке, а не в прошлом


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 224
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 16.10.06 11:21. Заголовок: Re:


Странно, а чем моя функция не понравилась?! Даже обидно!
Что касается сдвига, то интересный результат получается. Если делить 1 на 2 путем сдвига, то получаем 0. А если делить -1 на 2, то получаем снова -1! Так как знаковый бит из старшего бита постоянно сдвигается вправо, заполняя собой все число.


Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 31
Зарегистрирован: 07.08.06
ссылка на сообщение  Отправлено: 16.10.06 13:28. Заголовок: Re:


Володя, не обижайся, плз! : -))
Мне стыдно признаться, но я... не знаю, как твою ф-цию прислюнявить к своему коду (в АСМе я ничего не смыслю).
Кинь obj, если не затруднит, чтобы я его мог прилинковать к своей проге (blinker 6.0 extended mode).

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 225
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 16.10.06 14:23. Заголовок: Re:


p519446 пишет:

 цитата:
Кинь obj, если не затруднит


Не затруднит, но только смогу это сделать завтра, так как для этого нужно зайти домой.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 3
Зарегистрирован: 23.10.06
ссылка на сообщение  Отправлено: 23.10.06 16:09. Заголовок: Re:


p519446 пишет:

 цитата:
2) простой тест показал, что ф-ция NUMROL() работает МЕДЛЕННЕЕ, чем обычное умножение на 2 (200000 итераций выполнялось соотв-но 1.67" и 1.34"). Хотя я неоднократно слышал/читал, что бравые Си`шники и АСМ`еры никогда не умножают и не делят на число, равное степени 2 -- юзают вместо этого именно SHL/SHR. А в клиппере всё оказалось наоборот: надо забыть про эту идею и просто умножать/делить "как в школе учили", без извращений. Кто-нить может объяснить этот эффект ?



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

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 4
Зарегистрирован: 23.10.06
ссылка на сообщение  Отправлено: 23.10.06 16:11. Заголовок: Re:


Sergy пишет:

 цитата:
Странно требовать от языка высокого уровня высокой скорости обработки 16-битовых чисел.



собственно сдвиг в numrol или как там - выполняется микросекунды. основное время уходит на подготовку к вызову функции... а когда она отработала - пробирки опять тщательно моются)))

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 5
Зарегистрирован: 23.10.06
ссылка на сообщение  Отправлено: 23.10.06 16:14. Заголовок: Re:


p519446 пишет:

 цитата:
Кстати, вопрос: а что там будет в Vista ? DOS-машина умрёт окончательно или будет на что-то заменена ?



сегодня пытались провести брифинг по висте. но не смогли - все зависло нах ))))))

грят доса не будет))))

переживать первое время не стоит - не только дос, но и сама виста тоже работать первое время не будет

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 6
Зарегистрирован: 23.10.06
ссылка на сообщение  Отправлено: 23.10.06 16:16. Заголовок: Re:


p519446 пишет:

 цитата:
Кто-нибудь знает, есть ли в штатных средствах клиппера возможность выполнить над числом битовый сдвиг на N разрядов вправо/влево ? (т.е. не делить/умножать на степень числа 2, а именно СДВИНУТЬ биты исходного числа и получить результат, как в АСМе SHR/SHL)



чем тебе не нравится умножение и деление чисел? ))))

зы. у мине есть битовые сдвиги )) чо не просишь?

более того - даже не над числами (небольшое кол-во битов), а над СТРОКОЙ (большое кол-во битов)

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 34
Зарегистрирован: 07.08.06
ссылка на сообщение  Отправлено: 24.10.06 00:28. Заголовок: Re:


suv пишет:

 цитата:
сегодня пытались провести брифинг по висте. но не смогли - все зависло нах )))))) сегодня пытались провести брифинг по висте. но не смогли - все зависло нах ))))))


Сцылочку в студию кинул бы, что-ли... Чтобы хоть поржать немного над очередным шедевром.

suv пишет:

 цитата:
у мине есть битовые сдвиги )) чо не просишь?


Дык чего же ты молчишь-то ?!? Давай, плз!!

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 24 , стр: 1 2 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 609
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет