Здравствуйте, reversecode, Вы писали:
R>ннда R>если бы я в юности не программил на делфи R>а в старости не ревесил программы на делфи R>то наверное я бы и поддался вашим тезисам
Khimik не программист, а реальны химик. Ему чтобы нормально в программирование окунуться нужно года 2-3 учится.
Sic luceat lux!
Re[7]: Перевести код библиотеки xdr с C++ на Delphi
Здравствуйте, reversecode, Вы писали:
R>он 15 лет на форуме окунается R>пора бы уже
Человек правильно расставил приоритеты, лутает деньги с дельфии-симулятора и инвестирует в личную жизнь, а не учит это ваше программирование на С++ по 15 чтобы стать сениёром.
Sic luceat lux!
Re[3]: Перевести код библиотеки xdr с C++ на Delphi
Здравствуйте, Khimik, Вы писали:
K>Вы посмотрели функции receivebits и receiveints? Мне ещё не совсем понятно, если в молекуле 100 атомов, xyz координаты каждого упаковываются в одно число и эти числа идут друг за другом, или упаковка идёт ещё дальше и например координаты двух атомов это x1, x2, x3, x4, x5, x6 в вашем примере, которые упаковываются в единое многозначное число.
Смотрите исходник все просто кодируется. Даже описание в шапке есть:
/*____________________________________________________________________________
|
| xdr3dfcoord - read or write compressed 3d coordinates to xdr file.
|
| this routine reads or writes (depending on how you opened the file with
| xdropen() ) a large number of 3d coordinates (stored in *fp).
| The number of coordinates triplets to write is given by *size. On
| read this number may be zero, in which case it reads as many as were written
| or it may specify the number if triplets to read (which should match the
| number written).
| Compression is achieved by first converting all floating numbers to integer
| using multiplication by *precision and rounding to the nearest integer.
| Then the minimum and maximum value are calculated to determine the range.
| The limited range of integers so found, is used to compress the coordinates.
| In addition the differences between succesive coordinates is calculated.
| If the difference happens to be 'small' then only the difference is saved,
| compressing the data even more. The notion of 'small' is changed dynamically
| and is enlarged or reduced whenever needed or possible.
| Extra compression is achieved in the case of GROMOS and coordinates of
| water molecules. GROMOS first writes out the Oxygen position, followed by
| the two hydrogens. In order to make the differences smaller (and thereby
| compression the data better) the order is changed into first one hydrogen
| then the oxygen, followed by the other hydrogen. This is rather special, but
| it shouldn't harm in the general case.
|
*/
google translate:
эта процедура читает или записывает (в зависимости от того, как вы открыли файл с помощью xdropen())
большое количество трехмерных координат (хранящихся в *fp).
Количество записываемых троек координат определяется параметром *size.
При чтении это число может быть нулевым, и в этом случае он считывает столько же, сколько было записано,
или может указывать количество считываемых триплетов (которое должно совпадать с записанным числом).
Сжатие достигается путем предварительного преобразования всех плавающих чисел в целые числа с
использованием умножения на *точность и округления до ближайшего целого числа. Затем вычисляются
минимальное и максимальное значения для определения диапазона. Найденный таким образом ограниченный
диапазон целых чисел используется для сжатия координат. Кроме того, рассчитывается разница между
последовательными координатами. Если разница оказывается «небольшой», сохраняется только разница,
что еще больше сжимает данные. Понятие «маленького» динамически меняется и увеличивается или
уменьшается всякий раз, когда это необходимо или возможно. Дополнительное сжатие достигается в случае
GROMOS и координат молекул воды. GROMOS сначала записывает положение кислорода, а затем двух атомов
водорода. Чтобы сделать различия меньшими (и тем самым лучше сжать данные),
порядок изменяется: сначала один водород, затем кислород, а затем другой водород.
Это довольно специфическая ситуация, но в общем случае она не должна навредить.
K>Я в прошлом правил один код старой научной программы на фортране, и можно сказать был в шоке, насколько фортран неудобный язык или насколько этот код неправильно написан.
Зря вы гоните на фортран. Современный фортран позволяет писать достаточно выразительно.
Re[9]: Перевести код библиотеки xdr с C++ на Delphi
синьер нафиг не нужен
на том уровне что ему надо
я начал программить на с/c++ через месяц как увидел и научился включать комп
и мне показали на какие клавиши нажимать что бы запустить компиляцию
Re[7]: Перевести код библиотеки xdr с C++ на Delphi
Здравствуйте, Kernan, Вы писали:
R>>ннда R>>если бы я в юности не программил на делфи R>>а в старости не ревесил программы на делфи R>>то наверное я бы и поддался вашим тезисам K>Khimik не программист, а реальны химик. Ему чтобы нормально в программирование окунуться нужно года 2-3 учится.
Мне обидно слышать такие выпады, отвечу что я зарабатываю на шароваре, возможно, больше любого из вас, притом что у меня огромное количество времени уходит на науку, философию, политику и т.п. — кто читает мои посты на форуме, поймёт о чём я. Обычно все специалисты, один я могу на любую тему поговорить.
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Re[8]: Перевести код библиотеки xdr с C++ на Delphi
Очень грустно, что никто из обладателей GPT4 на этом форуме не откликнулся на мою просьбу. Казалось бы делов то — скопипастить ему четыре фрагмента кода, или только два первых, из третьего сообщения, плюс добавить "translate this code from C to Delphi programming language". Shmj, vsb, MaximVK, вы могли бы блеснуть суперспособностью...
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Здравствуйте, Khimik, Вы писали:
K>Мне надо перевести с C++ на Delphi фрагмент кода программы Gromacs, который читает файл с траекторией движения молекул.
А не лучше этот код на C++ в DLL засунуть и вызывать из Delphi?
Re[2]: Перевести код библиотеки xdr с C++ на Delphi
Здравствуйте, AleksandrN, Вы писали:
AN>А не лучше этот код на C++ в DLL засунуть и вызывать из Delphi?
А не дольше в DLL засовывать, чем переписать, руками? Особенно если у ТС нет опыта создания Сшных DLL и вызова их функций из Дельфи. Заодно и понять что код делает. Хотя похоже ТС хотелось использовать код не понимая этого.
Re[3]: Перевести код библиотеки xdr с C++ на Delphi
Здравствуйте, pagid_, Вы писали:
_>Заодно и понять что код делает.
Зачем? Ему же не ошибки в нем исправлять. Проще потратить время и разобраться как эту либу подружить с дельфи как есть, чем перепиливать ее на паскале. Наделает же ошибок в процессе. Это в довесок к тому, что потратит кучу времени на переписывание.
Re[2]: Перевести код библиотеки xdr с C++ на Delphi
Здравствуйте, Khimik, Вы писали:
K>Очень грустно, что никто из обладателей GPT4 на этом форуме не откликнулся на мою просьбу. Казалось бы делов то — скопипастить ему четыре фрагмента кода, или только два первых, из третьего сообщения, плюс добавить "translate this code from C to Delphi programming language". Shmj, vsb, MaximVK, вы могли бы блеснуть суперспособностью...
У меня нет GPT-4, но рискну предположить, что с первого раза он выдаст правдоподобную фигню, и начнется бесконечный цикл уточнений и правок, на который ни у кого нет времени.
Плюс, я не знаю, как низко надо ценить собственное время, чтобы было жалко потратить двадцатку на подписку самому, если это реально надо для бизнеса.
Да справляется GPT. Не греши за зря K>Первая половина:
GPT4
Here's a translation of the given C code to Delphi:
delphi
function xdr3dfcoord(xdrs: PXDR; fp: PSingle; var size: Integer; precision: PSingle): Integer;
const
MAXID = ...; // You should define this value, it was not in the original code.
FIRSTIDX = ...; // Similarly, define this value.
LASTIDX = ...; // And this value.var
ip, buf: PInteger;
oldsize: Integer;
minint, maxint, prevcoord: array[0..2] of Integer;
mindiff, diff, lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx: Integer;
minidx, maxidx, flag, k, smallnum, smaller, larger, i, is_small, is_smaller: Integer;
run, prevrun, tmp, bufsize, xdrid, lsize: Integer;
bitsize: Cardinal;
size3: Cardinal;
sizeint, sizesmall, bitsizeint: array[0..2] of Cardinal;
luip: PCardinal;
lfp: PSingle;
lf: Single;
thiscoord: PInteger;
tmpcoord: array[0..29] of Cardinal;
inv_precision: Single;
errval: Integer = 1;
begin
bitsizeint[0] := 0;
bitsizeint[1] := 0;
bitsizeint[2] := 0;
prevcoord[0] := 0;
prevcoord[1] := 0;
prevcoord[2] := 0;
// Assuming xdridptr and xdrmodes are external/global arrays. Their types and sizes are not defined in the provided code.
xdrid := 0;
while (xdridptr[xdrid] <> xdrs) do
begin
Inc(xdrid);
if (xdrid >= MAXID) then
begin
WriteLn('xdr error. no open xdr stream');
Halt(1);
end;
end;
if (xdrmodes[xdrid] = 'w') or (xdrmodes[xdrid] = 'a') then
begin// Code for writing mode is skipped as per the original.end
else
begin// Reading modeif (xdr_int(xdrs, lsize) = 0) then
Exit(0);
if (size <> 0) and (lsize <> size) then
WriteLn(Format('wrong number of coordinates in xdr3dfcoord; %d arg vs %d in file', [size, lsize]));
size := lsize;
size3 := Cardinal(size) * 3;
if size <= 9 then
begin
precision^ := -1;
Exit(xdr_vector(xdrs, PChar(fp), size3, SizeOf(Single), @xdr_float));
end;
xdr_float(xdrs, precision^);
if ip = nil then
begin
GetMem(ip, size3 * SizeOf(Integer));
if ip = nil then
begin
WriteLn('malloc failed');
Halt(1);
end;
bufsize := Trunc(size3 * 1.2);
GetMem(buf, bufsize * SizeOf(Integer));
if buf = nil then
begin
WriteLn('malloc failed');
Halt(1);
end;
oldsize := size;
end
else if size > oldsize then
begin
ReallocMem(ip, size3 * SizeOf(Integer));
if ip = nil then
begin
WriteLn('malloc failed');
Halt(1);
end;
bufsize := Trunc(size3 * 1.2);
ReallocMem(buf, bufsize * SizeOf(Integer));
if buf = nil then
begin
WriteLn('malloc failed');
Halt(1);
end;
oldsize := size;
end;
buf[0] := 0;
buf[1] := 0;
buf[2] := 0;
xdr_int(xdrs, minint[0]);
xdr_int(xdrs, minint[1]);
xdr_int(xdrs, minint[2]);
xdr_int(xdrs, maxint[0]);
xdr_int(xdrs, maxint[1]);
xdr_int(xdrs, maxint[2]);
sizeint[0] := Cardinal(maxint[0] - minint[0] + 1);
sizeint[1] := Cardinal(maxint[1] - minint[1] + 1);
sizeint[2] := Cardinal(maxint[2] - minint[2] + 1);
// Assuming sizeofint and sizeofints are functions you have elsewhereif (sizeint[0] or sizeint[1] or sizeint[2]) > $ffffff then
begin
bitsizeint[0] := sizeofint(sizeint[0]);
bitsizeint[1] := sizeofint(sizeint[1]);
bitsizeint[2] := sizeofint(sizeint[2]);
bitsize := 0; // Flag the use of large sizesend
else
bitsize := sizeofints(3, @sizeint);
if xdr_int(xdrs, smallidx) = 0 then
Exit(0);
maxidx := Min(LASTIDX, smallidx + 8);
minidx := maxidx - 8; // Often this equals smallidx
// Assuming magicints is an external/global array
smaller := magicints[Max(FIRSTIDX, smallidx-1)] div 2;
smallnum := magicints[smallidx] div 2;
sizesmall[0] := magicints[smallidx];
sizesmall[1] := magicints[smallidx];
sizesmall[2] := magicints[smallidx];
larger := magicints[maxidx];
// buf[0] holds the length in bytesif xdr_int(xdrs, buf[0]) = 0 then
Exit(0);
if xdr_opaque(xdrs, PChar(@buf[3]), buf[0]) = 0 then
Exit(0);
buf[0] := 0;
buf[1] := 0;
buf[2] := 0;
lfp := fp;
inv_precision := 1.0 / precision^;
run := 0;
i := 0;
lip := ip;
end;
Result := 1;
end;
Please note the following:
You will need to adjust the constants (MAXID, FIRSTIDX, LASTIDX) as they were not provided in the original C code.
Some functions like xdr_int, xdr_vector, xdr_float, sizeofint, sizeofints, and the global arrays xdridptr, xdrmodes, and magicints are assumed to be available elsewhere, as they were referred to in the C code but not provided.
You might need to make adjustments based on your actual implementation and requirements.
This code was translated to the best of my understanding and may need adjustments for the actual purpose.
Извиняюсь за то, что спросил машину на вражеском, переспрашивать лень было.
Re[3]: Перевести код библиотеки xdr с C++ на Delphi
Здравствуйте, Khimik, Вы писали:
K>Мне надо перевести с C++ на Delphi фрагмент кода программы Gromacs, который читает файл с траекторией движения молекул.
Как уже советовали выше — прилинковать готовый код проще, или статически (lib), или динамически (dll).
При трансляции неизбежно трудноуловимых ошибок наделаешь...
Sine vilitate, sine malitiosa mente
Re[4]: Перевести код библиотеки xdr с C++ на Delphi
Здравствуйте, Khimik, Вы писали: K>>>Первая половина: K>Можно ещё вторую половину, раз уж начали?
Вторая половина
function xdr3dfcoord(xdrs: PXDR; fp: PSingle; var size: Integer; precision: PSingle): Integer;
const
MAXID = ...; // Define this value; it was not in the original code.
FIRSTIDX = ...; // Similarly, define this value.var
ip: PInteger = nil;
oldsize: Integer;
buf: PInteger;
minint, maxint, lip, thiscoord, prevcoord: array[0..2] of Integer;
mindiff, diff, lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx: Integer;
minidx, maxidx, flag, k, smallnum, smaller, larger, i, is_small, is_smaller: Integer;
run, tmp, bufsize, xdrid, lsize: Integer;
sizeint, sizesmall, bitsizeint: array[0..2] of Cardinal;
size3: Cardinal;
luip: PCardinal;
lfp: PSingle;
lf, inv_precision: Single;
bitsize: Cardinal;
errval: Integer = 1;
begin
bitsizeint[0] := 0;
bitsizeint[1] := 0;
bitsizeint[2] := 0;
prevcoord[0] := 0;
prevcoord[1] := 0;
prevcoord[2] := 0;
xdrid := 0;
while (xdridptr[xdrid] <> xdrs) do
begin
Inc(xdrid);
if (xdrid >= MAXID) then
begin
WriteLn('xdr error. no open xdr stream');
Halt(1);
end;
end;
if (xdrmodes[xdrid] = 'w') or (xdrmodes[xdrid] = 'a') then
begin// xdrs is open for writing – code skippedend
else
begin
i := 0;
while (i < lsize) do
begin
thiscoord := PInteger(lip) + i * 3;
if (bitsize = 0) then
begin
thiscoord[0] := receivebits(buf, bitsizeint[0]);
thiscoord[1] := receivebits(buf, bitsizeint[1]);
thiscoord[2] := receivebits(buf, bitsizeint[2]);
end
else
begin
receiveints(buf, 3, bitsize, sizeint, thiscoord);
end;
Inc(i);
Inc(thiscoord[0], minint[0]);
Inc(thiscoord[1], minint[1]);
Inc(thiscoord[2], minint[2]);
prevcoord[0] := thiscoord[0];
prevcoord[1] := thiscoord[1];
prevcoord[2] := thiscoord[2];
flag := receivebits(buf, 1);
is_smaller := 0;
if (flag = 1) then
begin
run := receivebits(buf, 5);
is_smaller := run mod 3;
Dec(run, is_smaller);
Dec(is_smaller);
end;
if (run > 0) then
begin
Inc(thiscoord, 3);
for k := 0 to run-1 do
begin
receiveints(buf, 3, smallidx, sizesmall, thiscoord);
Inc(i);
Inc(thiscoord[0], prevcoord[0] - smallnum);
Inc(thiscoord[1], prevcoord[1] - smallnum);
Inc(thiscoord[2], prevcoord[2] - smallnum);
if (k = 0) then
begin// interchange first with second atom for better compression of water molecules
tmp := thiscoord[0];
thiscoord[0] := prevcoord[0];
prevcoord[0] := tmp;
tmp := thiscoord[1];
thiscoord[1] := prevcoord[1];
prevcoord[1] := tmp;
tmp := thiscoord[2];
thiscoord[2] := prevcoord[2];
prevcoord[2] := tmp;
lfp^ := prevcoord[0] * inv_precision; Inc(lfp);
lfp^ := prevcoord[1] * inv_precision; Inc(lfp);
lfp^ := prevcoord[2] * inv_precision; Inc(lfp);
end
else
begin
prevcoord[0] := thiscoord[0];
prevcoord[1] := thiscoord[1];
prevcoord[2] := thiscoord[2];
end;
lfp^ := thiscoord[0] * inv_precision; Inc(lfp);
lfp^ := thiscoord[1] * inv_precision; Inc(lfp);
lfp^ := thiscoord[2] * inv_precision; Inc(lfp);
end;
end
else
begin
lfp^ := thiscoord[0] * inv_precision; Inc(lfp);
lfp^ := thiscoord[1] * inv_precision; Inc(lfp);
lfp^ := thiscoord[2] * inv_precision; Inc(lfp);
end;
Inc(smallidx, is_smaller);
if (is_smaller < 0) then
begin
smallnum := smaller;
if (smallidx > FIRSTIDX) then
smaller := magicints[smallidx - 1] div 2
else
smaller := 0;
end
else if (is_smaller > 0) then
begin
smaller := smallnum;
smallnum := magicints[smallidx] div 2;
end;
sizesmall[0] := magicints[smallidx];
sizesmall[1] := magicints[smallidx];
sizesmall[2] := magicints[smallidx];
end;
end;
Result := 1;
end;
Notes:
I'm assuming that PXDR, receivebits, receiveints, xdridptr, xdrmodes, and magicints are available elsewhere in your Delphi code as they were referred to in the C code but not provided.
The syntax for pointer arithmetic in Delphi is a little different from C. I've made adjustments accordingly.
Delphi uses div for integer division instead of /.
You'll need to define or replace MAXID, FIRSTIDX, and other constants and data types that were not provided in the original C code.
Some of the data structures and functions might need to be adjusted depending on the specifics of your Delphi implementation.
Always review and test the code thoroughly before integrating it into your project.
А ещё он привет тебе передавал, сказал завтра зайдёт.
...Шутка
Re[5]: Перевести код библиотеки xdr с C++ на Delphi
const
BYTES_PER_XDR_UNIT = ...; // Define this value, it was not provided in the original code.type
TXDROperation = (XDR_DECODE, XDR_ENCODE, XDR_FREE);
PXDR = ^TXDR;
TXDR = record
x_op: TXDROperation;
// ... other fields might be present, they were not provided in the C code.end;
function sizeofints(const num_of_ints: Integer; sizes: PCardinal): Integer;
var
i, num, bytecnt: Integer;
num_of_bytes, num_of_bits, tmp: Cardinal;
bytes: array[0..31] of Cardinal;
begin
num_of_bytes := 1;
bytes[0] := 1;
num_of_bits := 0;
for i := 0 to num_of_ints - 1 do
begin
tmp := 0;
bytecnt := 0;
while bytecnt < num_of_bytes do
begin
tmp := bytes[bytecnt] * sizes[i] + tmp;
bytes[bytecnt] := tmp and $FF;
tmp := tmp shr 8;
Inc(bytecnt);
end;
while tmp <> 0 do
begin
bytes[bytecnt] := tmp and $FF;
tmp := tmp shr 8;
Inc(bytecnt);
end;
num_of_bytes := bytecnt;
end;
num := 1;
Dec(num_of_bytes);
while bytes[num_of_bytes] >= num do
begin
Inc(num_of_bits);
num := num * 2;
end;
Result := num_of_bits + num_of_bytes * 8;
end;
function receivebits(buf: PInteger; num_of_bits: Integer): Integer;
var
cnt, mask, num: Integer;
lastbits, lastbyte: Cardinal;
cbuf: PByte;
begin
cbuf := PByte(buf) + 3 * SizeOf(buf^);
cnt := buf[0];
lastbits := Cardinal(buf[1]);
lastbyte := Cardinal(buf[2]);
num := 0;
while num_of_bits >= 8 do
begin
lastbyte := (lastbyte shl 8) or cbuf[cnt];
Inc(cnt);
num := num or ((lastbyte shr lastbits) shl (num_of_bits - 8));
Dec(num_of_bits, 8);
end;
if num_of_bits > 0 then
begin
if lastbits < num_of_bits then
begin
lastbits := lastbits + 8;
lastbyte := (lastbyte shl 8) or cbuf[cnt];
Inc(cnt);
end;
Dec(lastbits, num_of_bits);
num := num or ((lastbyte shr lastbits) and ((1 shl num_of_bits) - 1));
end;
mask := (1 shl num_of_bits) - 1;
num := num and mask;
buf[0] := cnt;
buf[1] := Integer(lastbits);
buf[2] := Integer(lastbyte);
Result := num;
end;
procedure receiveints(buf: PInteger; const num_of_ints, num_of_bits: Integer; sizes: PCardinal; nums: PInteger);
var
bytes: array[0..31] of Integer;
i, j, num_of_bytes, p, num: Integer;
begin
bytes[1] := 0;
bytes[2] := 0;
bytes[3] := 0;
num_of_bytes := 0;
while num_of_bits > 8 do
begin
bytes[num_of_bytes] := receivebits(buf, 8);
Inc(num_of_bytes);
Dec(num_of_bits, 8);
end;
if num_of_bits > 0 then
begin
bytes[num_of_bytes] := receivebits(buf, num_of_bits);
Inc(num_of_bytes);
end;
for i := num_of_ints - 1 downto 1 do
begin
num := 0;
for j := num_of_bytes - 1 downto 0 do
begin
num := (num shl 8) or bytes[j];
p := num div sizes[i];
bytes[j] := p;
num := num - p * sizes[i];
end;
nums[i] := num;
end;
nums[0] := bytes[0] or (bytes[1] shl 8) or (bytes[2] shl 16) or (bytes[3] shl 24);
end;
function xdr_opaque(xdrs: PXDR; cp: PAnsiChar; cnt: Cardinal): Boolean;
var
rndup: Cardinal;
crud: array[0..BYTES_PER_XDR_UNIT - 1] of AnsiChar;
begin
Result := True;
if cnt = 0 then
Exit;
rndup := cnt mod BYTES_PER_XDR_UNIT;
if rndup > 0 then
rndup := BYTES_PER_XDR_UNIT - rndup;
case xdrs^.x_op of
XDR_DECODE:
begin
if not xdr_getbytes(xdrs, cp, cnt) then
Result := False
else if rndup = 0 then
Result := True
else
Result := xdr_getbytes(xdrs, crud, rndup);
end;
XDR_ENCODE:
begin
if not xdr_putbytes(xdrs, cp, cnt) then
Result := False
else if rndup = 0 then
Result := True
else
Result := xdr_putbytes(xdrs, xdr_zero, rndup); // Assuming xdr_zero is defined elsewhere in your codeend;
XDR_FREE:
Result := True;
else
Result := False;
end;
end;
Notes:
I have made certain assumptions about data structures (TXDR, etc.) and functions (xdr_getbytes, xdr_putbytes, etc.) because they were referred to in the C code but not provided. You may need to adjust accordingly based on your actual definitions and requirements.
PAnsiChar is used instead of char* in Delphi. It's assumed the char in your C code refers to an 8-bit character.
You should thoroughly review and test this translation to ensure correctness and compatibility with your Delphi environment and project requirements.