2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу Пред.  1 ... 36, 37, 38, 39, 40, 41, 42  След.
 
 Re: Как писать быстрые программы
Сообщение09.02.2026, 13:16 
Аватара пользователя
Ну вот я кстати попробовал простейшую программу написать и скомпилить:

Код:
/*
GP;init_RabUb_1();
*/
potok = 1;

Уж казалось бы, куда проще. И вот во что он её превратил командой

Код:
gp2c-run -g RabUb_1.gp


Это файл С:

(Оффтоп)

Код:
/*-*- compile-command: "cc -c -o RabUb_1.gp.o -g -O3 -Wall -fomit-frame-pointer -fno-strict-aliasing -fPIC -I\"/usr/include/x86_64-linux-gnu\" RabUb_1.gp.c && cc -o RabUb_1.gp.so -shared -g -O3 -Wall -fomit-frame-pointer -fno-strict-aliasing -fPIC -Wl,-shared -Wl,-z,relro RabUb_1.gp.o -lc -lm -L/usr/lib/x86_64-linux-gnu -lpari"; -*-*/
#include <pari/pari.h>
/*
GP;install("init_RabUb_1","v","init_RabUb_1","./RabUb_1.gp.so");
*/
void init_RabUb_1(void);
/*End of prototype*/

static GEN /*
GP;init_RabUb_1();
*/
potok;
/*End of global vars*/

void
init_RabUb_1(void)     /* void */
{
  pari_sp ltop = avma;
  potok = pol_x(fetch_user_var("potok"));
  /*
  GP;init_RabUb_1();
  */
  potok = gen_1;
  potok = gerepilecopy(ltop, potok);
  return;
}

 
 
 
 Re: Как писать быстрые программы
Сообщение09.02.2026, 13:51 
Yadryara в сообщении #1717592 писал(а):
Ура. Я так понял что эта команда убрала лишние символы, которые как-то появились.
Обратите внимание, что эта команда не проверяет количество лишних символов в конце строки.
Это просто фича.
(Пишу на случай если, случайно, несколько раз подряд, один и тот-же код прогонялся через исходную программу unix2dos.
Т.к. dos2unix это только ссылка на unix2dos.)

Вообще, когда часто приходится редактировать код "для другой" системы, можно применять такую программу как notepad++ вместо классического блокнота виндовс.
У нее можно поставить галочку в "View->Show symbol->Show all characters" и видеть текущий конец строк.
В "Encoding->Encode in ANSI" - получим кодировку классическую.
(Если нужен UTF текст, то для линукса будет "Encoding->Encode in UTF without BOM".
Но это Вам вряд-ли потребуется, вроде у Вас вывода в консоль на русском языке нет.)

А поменять конец строки можно по Ctrl+H, выставив
1. в "Find what:" \r\n
2. в "Replace with:" \n
3. в "Search mode" установить "Extended"

 
 
 
 Re: Как писать быстрые программы
Сообщение09.02.2026, 14:08 
Аватара пользователя
DemISdx, Спасибо. Сейчас пока всё работает без доп. ухищрений.

Я грешу на то, что эти "возвраты каретки" (термин-то от пишущей машинки) появились не в Win-Блокноте, а на форуме, я же ведь код с форума скопировал.

Потому что я в Блокноте с тех пор регулярно редактирую и запуск пока проходил нормально.

 
 
 
 Re: Как писать быстрые программы
Сообщение09.02.2026, 16:29 
Yadryara в сообщении #1717803 писал(а):
my(n0a=n0*v[ip+1]):int; — работает.

my(n0a=n0*v[ip+1]):small; — не работает. Пишет

Потому что int (в конкретном контексте) - это длинное (произвольной точности) целое. А small -- 32/64 битное (ulong).

 
 
 
 Re: Как писать быстрые программы
Сообщение09.02.2026, 16:31 
Yadryara в сообщении #1717831 писал(а):
DemISdx, Спасибо. Сейчас пока всё работает без доп. ухищрений.

Я грешу на то, что эти "возвраты каретки" (термин-то от пишущей машинки) появились не в Win-Блокноте, а на форуме, я же ведь код с форума скопировал.

Потому что я в Блокноте с тех пор регулярно редактирую и запуск пока проходил нормально.
На самом деле wrest сразу написал все достаточно точно:
wrest в сообщении #1717595 писал(а):
там используется перевод строки без предварительного возврата каретки, и возврат каретки может вызывать проблемы, иногда. Вот вы на такую проблему и натолкнулись.
Ключевое слово "может".

 
 
 
 Re: Как писать быстрые программы
Сообщение09.02.2026, 16:40 
Аватара пользователя
my(m = 6*lcm(v)/aa):int;

Я правильно понимаю, что вот такое объявление всё же лучше сделать, чем не сделать никакого?

Потому что теперь уже в си-коде нет static GEN m;

 
 
 
 Re: Как писать быстрые программы
Сообщение09.02.2026, 17:08 
Yadryara в сообщении #1717803 писал(а):
Да, там есть static GEN n0;

Это значит, что в .с переменная объявлена как произвольной точности (длинная). Даже необязательно целая.

 
 
 
 Re: Как писать быстрые программы
Сообщение09.02.2026, 18:51 
Yadryara в сообщении #1717823 писал(а):
Уж казалось бы, куда проще. И вот во что он её превратил командой

Ну да, так и есть. :D Пугаться не надо. Вас интересуют места, где в циклах, особенно во внутренних, вместо короткой арифметики типа a=b+c начинает появляться что-то типа a=gadd(b,c)

-- 09.02.2026, 18:58 --

wrest в сообщении #1717888 писал(а):
правильно понимаю, что вот такое объявление всё же лучше сделать, чем не сделать никакого?

Потому что теперь уже в си-коде нет static GEN m;

Нет, особо не лучше. С :int, это всё равно получается длинная переменная.

 
 
 
 Re: Как писать быстрые программы
Сообщение09.02.2026, 19:10 
Аватара пользователя
wrest в сообщении #1717912 писал(а):
:D Пугаться не надо.

Не то чтобы пугаюсь, но я же ничегошеньки не понял, зачем столько текста.

wrest в сообщении #1717912 писал(а):
Вас интересуют места, где в циклах, особенно во внутренних, вместо короткой арифметики типа a=b+c начинает появляться что-то типа a=gadd(b,c)

Другое дело. Вот это уже конкретика пошла.

wrest в сообщении #1717888 писал(а):
это всё равно получается длинная переменная.

Ну а короткая ведь и невозможна для 30+ значных чисел. На правильную попытку объявления смолом (через my()) Убунта ругается.

 
 
 
 Re: Как писать быстрые программы
Сообщение09.02.2026, 19:15 
Yadryara в сообщении #1717914 писал(а):
Ну а короткая ведь и невозможна для 30+ значных чисел.

Ну да. В принципе, действительно :int будет все-тки получше чем совсем без объявления.
Об этом пишут тут https://pari.math.u-bordeaux.fr/pub/par ... /gp2c.html в пункте 3.5 Example of optimisation

 
 
 
 Re: Как писать быстрые программы
Сообщение12.02.2026, 04:32 
Аватара пользователя
Всё чудесатее и чудесатее. Транслятор простых вещей не понимает.

Код:
/*
GP;init_RabUb_3();
*/
print(pro = 31*37*41*43*47*53);


Код:
yadryara@DESKTOP-QPP2F5P:~/Simple$ gp2c-run -g RabUb_3.gp
RabUb_3.gp.c: In function ‘init_RabUb_3’:
RabUb_3.gp.c:20:57: warning: integer overflow in expression of type ‘int’ results in ‘742235755’ [-Woverflow]
   20 |   pari_printf("%Ps\n", pro = stoi(((((31*37)*41)*43)*47)*53));
      |                                                         ^
742235755
?


А при замене на print(pro = vecprod([31,37,41,43,47,53])); уже отрабатывает корректно.

Код:
yadryara@DESKTOP-QPP2F5P:~/Simple$ gp2c-run -g RabUb_3.gp
5037203051
?

 
 
 
 Re: Как писать быстрые программы
Сообщение12.02.2026, 09:30 
Yadryara в сообщении #1718098 писал(а):
Всё чудесатее и чудесатее. Транслятор простых вещей не понимает.

Ну он честно предупреждает, что будет переполнение, и далее отрезаются биты старше 32-го.
Код:
? digits(5037203051,2)
%1 = [1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1]
? digits(742235755,2)
%2 = [1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1]
?

Как видите, у чисел совпадают биты с 1 по 32.

 
 
 
 Re: Как писать быстрые программы
Сообщение12.02.2026, 09:59 
Аватара пользователя
Значит объявление типа не просто лучше, а оно по сути обязательно, раз уж он не может нормально перемножить всего лишь 6 двузначных чисел.

Лучше тогда вот так изобразить:

Код:
  100101100001111011001111001101011
   00101100001111011001111001101011

 
 
 
 Re: Как писать быстрые программы
Сообщение12.02.2026, 10:42 
Yadryara в сообщении #1718104 писал(а):
раз уж он не может нормально перемножить

"Он" может, но действительно странно, что применяется stoi() - это функция конвертации сишного long в pari-шный int (длинный)
Дело тут в том, что правую часть, а именно строку 31*37*41*43*47*53 транслятор считает коротким числом.

Неожиданно, да :D

 
 
 
 Re: Как писать быстрые программы
Сообщение12.02.2026, 14:09 
Аватара пользователя
Реализую более сложную идею и вот мне понадобилось ещё внешний цикл добавить. Между тем, синтаксиса этого я не знаю. Понимаю только что echo это же не совсем print :-)

Код:
#!/bin/bash

for i in {1..3}; do
for j in {1..16}; do
    echo ${i} >           nom0_test.input
    echo ${j} >           nom0_test.input
    chmod 666   RabUb_400_un_0_1.gp
    gp2c-run -g RabUb_400_un_0_1.gp
done
done

Записывает только нижнее число, то есть только j. Или перезаписывает j поверх i.

То есть мне надо в файл как-то напечатать два числа. Если одно записать под другим, на разных строках, то получается считать вот так:

Код:
nomera = read("nom0_test.input");

my(noraskv = nomera[1]):small;
my(nomin = nomera[2]):small;

 
 
 [ Сообщений: 628 ]  На страницу Пред.  1 ... 36, 37, 38, 39, 40, 41, 42  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group