LINUX.ORG.RU

Как математически разбить диапазон hex?

 , ,


1

1
print(hex2part(num=1, part=3))

out:

[['0x0', '0x4'], ['0x5', '0x9'], ['0xa', '0xe']]

Сейчас это работает, но я применил range диапазона. Как можно догадаться, чем больше num, тем медленней это делается

print(hex2part(num=7, part=3))

out:

time ./test.py
[['0x0', '0x5555554'], ['0x5555555', '0xaaaaaa9'], ['0xaaaaaaa', '0xffffffe']]

real    0m9.491s
user    0m7.010s
sys     0m2.479s

Как бы всё это сделать на уровне математики, чтобы не прибегать к использованию range?

★★★

Последнее исправление: serg002 (всего исправлений: 1)

Код целиком выложи, не понятно нифига. Что за hex диапазоны, что творится внутри hex2part? Бинарные данные хранишь в представлении строки в hex и удивляешься, что работает медленно?

Как можно догадаться,

Нельзя.

anonymous
()
Ответ на: комментарий от anonymous

ППКС. hex — способ записи числа, оперируй над числами, разбивай математически. Если хочешь что-то спросить, спрашивай со всем контекстом, приводи минимальный самодостаточный тормозящий пример целиком.

t184256 ★★★★★
()

Так?

MODULE A;
	IMPORT Log := StdLog, In := i21sysIn;
	
	PROCEDURE Do*;
		VAR num, part: INTEGER; max: LONGINT; i: INTEGER;
	BEGIN
		In.Open; ASSERT(In.done);
		In.Int(num); In.Int(part); ASSERT(In.done);
		max := ASH(1, 4*LONG(num)) - 1;
		i := 0; WHILE i < part DO
			Log.IntForm(max * i DIV (part), 16, 0, "0", FALSE); Log.String(", ");
			Log.IntForm(max * (i + 1) DIV (part) - 1, 16, 0, "0", FALSE);
			Log.Ln;
		INC(i) END;
	END Do;
	
END A.

(!)A.Do 1 3
0, 4
5, 9
A, E
(!)A.Do 7 3
0, 5555554
5555555, AAAAAA9
AAAAAAA, FFFFFFE
X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
fubar = lambda number, lowbit, highbit: (number >> lowbit) & ((1 << (highbit - lowbit + 1)) - 1)

вырезает из числа указанные биты, нумерация разрядов с 0.

>>> hex(fubar(int('1234567890ABCDEF', 16), 32, 47))
'0x5678'

вырезаны биты с 32 по 47 включительно.

1 hex цифра - это 4 бита, младшая цифра - биты с 0 по 3, следующая с 4 по 7, и т.д.

Это нужно или чтото другое?

anonymous
()
Ответ на: комментарий от anonymous
print(hex2part(num=1, part=3))
[['0x0', '0x4'], ['0x5', '0x9'], ['0xa', '0xf']]

print(hex2part(num=2, part=3))
[['0x0', '0x54'], ['0x55', '0xa9'], ['0xaa', '0xff']]

print(hex2part(num=3, part=3))
[['0x0', '0x554'], ['0x555', '0xaa9'], ['0xaaa', '0xfff']]
serg002 ★★★
() автор топика
Последнее исправление: serg002 (всего исправлений: 1)

Просто используй матоперации, чтобы разбить диапазон на несколько нужных, а потом померяй время, по сравнению поймёшь насколько быстрее.

anonymous
()
Ответ на: комментарий от serg002
>>> def hex2part(num, part):
...   max = (1 << (num * 4)) - 1
...   step = max // part
...   last = step * (part - 1)
...   return [[hex(i), hex(max if i == last else (i + step - 1))] for i in range(0, last + 1, step)]
...
>>>
>>>
>>> hex2part(1, 3)
[['0x0', '0x4'], ['0x5', '0x9'], ['0xa', '0xf']]
>>> hex2part(7, 3)
[['0x0', '0x5555554'], ['0x5555555', '0xaaaaaa9'], ['0xaaaaaaa', '0xfffffff']]
>>> hex2part(4, 5)
[['0x0', '0x3332'], ['0x3333', '0x6665'], ['0x6666', '0x9998'], ['0x9999', '0xcccb'], ['0xcccc', '0xffff']]
>>> hex2part(3, 10)
[['0x0', '0x198'], ['0x199', '0x331'], ['0x332', '0x4ca'], ['0x4cb', '0x663'], ['0x664', '0x7fc'], ['0x7fd', '0x995'], ['0x996', '0xb2e'], ['0xb2f', '0xcc7'], ['0xcc8', '0xe60'], ['0xe61', '0xfff']]
>>> hex2part(1, 10)
[['0x0', '0x0'], ['0x1', '0x1'], ['0x2', '0x2'], ['0x3', '0x3'], ['0x4', '0x4'], ['0x5', '0x5'], ['0x6', '0x6'], ['0x7', '0x7'], ['0x8', '0x8'], ['0x9', '0xf']]
>>>
anonymous
()
Ответ на: комментарий от anonymous

Не самое лучшее решение, наверное. Набросал навскидку. Все, что не режется поровну, улетает в последнюю часть, которая будет больше всех.

Если не секрет - нафига это надо?

anonymous
()
Ответ на: комментарий от X512

хехе, паскалик с причмоком у пистона по выразительности. 4 строки против скольких?

2021 год на дворе, проснись!

anonymous
()
Ответ на: комментарий от serg002

а что не так с range ?

ну все равно каким то способом надо будет итерировать счетчик. чем плох range?

также, никакого замедления не обнаружил при больших num (вплоть до 100).

anonymous
()
Ответ на: комментарий от anonymous

в данном конкретном случае всё отлично!

serg002 ★★★
() автор топика
Ответ на: комментарий от X512

Ужас какой. Вот как надо

ФУНК РАЗБИТЬ(ЧИCЛO,ЧACTИ);
  <>->A;  
  ЧИCЛO//ЧACTИ+1->ШAГ; 
  ДЛЯ И OT 1 ДO ЧACTИ-1::
     A+<<ШAГ*(И-1),ШAГ*И-1>>->A;                              
  BCE;
  A+<<ШAГ*(ЧACTИ-1),ЧИCЛO>>->A;
  РЕЗ:А;             
KHЦ;


# ? РАЗБИТЬ(14,3);

<<0,4>,<5,9>,<10,14>>

# ? РАЗБИТЬ(2**28-2,3);

<<0,89478484>,<89478485,178956969>,<178956970,268435454>> 
anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.