electrik | Дата: Пятница, 23.10.2015, 21:50 | Сообщение # 1 |
Полковник
Группа: Друзья
Сообщений: 182
Статус: Offline
| данная функция преобразует число байт в удобочитабельный вид, мегабайт, гигабайт, эксабайт.
Код function ConvertBytes(byval nBytes as ulongint) as string static as const zstring ptr nTable(0 to ...) = { _ ' таблица названий единиц измерения @"B", _ ' байт @"KB", _ ' килобайт @"MB", _ ' мегабайт @"GB", _ ' гигабайт @"TB", _ ' терабайт @"PB", _ ' петабайт @"EB"} ' эксабайт ' @"ZB", _ ' зеттабайт (зарезервирован для чисел больше 64 бит) ' @"Yb"} ' йоттабайт (зарезервирован для чисел больше 64 бит)
static as const ulongint NumTable(1 to ...) = { _ ' таблица измерений 1*1024, _ ' один килобайт 1024^2, _ ' один мегабайт 1024^3, _ ' один гигабайт 1024^4, _ ' один терабайт 1024^5, _ один петабайт 1024^6} ' один эксабайт ' 1024^7, _ ' один зеттабайт (зарезервирован для чисел больше 64 бит) ' 1024^8} ' один йоттабайт (зарезервирован для чисел больше 64 бит)
for i as integer = 6 to 0 step -1 if i then if nBytes >= numTable(i) then dim n as single = nBytes/numTable(i) return str(fix(n)) & iif(frac(n),","," ") & mid(str(frac(n)),3,2) & " " & *nTable(i) end if else return str(nBytes) & " " & *nTable(i) end if next end function
?convertbytes(0) ?convertbytes(9) ?convertbytes(321) ?convertbytes(1024) ?convertbytes(3765135) ?convertbytes(318757523456) ?convertbytes(77313757523456) ?convertbytes(5863547645444479735) sleep
|
|
| |
Somerick | Дата: Воскресенье, 07.08.2016, 05:49 | Сообщение # 2 |
Рядовой
Группа: Пользователи
Сообщений: 14
Статус: Offline
| Есть WinAPI функции для подобного форматирования. StrFormatByteSize и StrFormatByteSize64 параметры: число байт, указатель на буфер, длина буфера.
Код #Include Once"windows.bi" #Include Once"win\shlwapi.bi" Dim As ZString*32 s=Any
'принимает число qword(longint) StrFormatByteSize64 17063937332667,@s,30
MessageBox 0,s,"",0 'показ результата "15,5 ТБ"
'принимает dword(integer) StrFormatByteSize 9873685,@s,30
MessageBox 0,s,"",0 'показ результата "9,41 МБ"; при 1024 будет: "1,00 КБ"; при 1: "1 байт"
И ещё вот самодельный ассемблерный вариант, по идее кроссплатформенный x86. При конвертации не используются: вызовы других ф-ций кроме этих 3, инструкции операций с числами с плавающей точкой, только целочисленные.
Код 'число байт b пишется в строку s с форматом и приставкой B\KB\MB\GB Declare Function Byteconvert(b As Long,s As ZString Ptr)As ZString Ptr Declare Function Byteconvert64(b As LongInt,s As ZString Ptr)As ZString Ptr 'Byteconvert принимает число от 0 до 2147483647 'если стоит задача конвертировать всегда только до 2 GB, функция Byteconvert64 не нужна.
'число l пишется в строку s; zltoa l,s по действию эквивалент С-функции _ltoa l,s,10 Declare Function zltoa(l As Long,s As ZString Ptr)As ZString Ptr 'возвращаемое значение всех трёх функций - указатель на конец строки. 'Его можно использовать чтоб приcоединять другие строки или для подсчёта числа символов путём вычета начала. Dim As ZString*32 s=Any Dim As ZString Ptr p=zltoa(123,s)'s = "123" Dim As Long x=p-@s'x = 3 пример получения длины Poke Short,p,66's = "123B" пример использования конечного указателя '?x '?s
'пример конвертации. Dim As LongInt li=Any ?"Exit: enter -1" Do Input "Bytes: ",li'Вводить число байт. If li=-1 Then Exit Do'выход из программы
Byteconvert64 li,s ?li; " - "; s Loop
Function Byteconvert naked(b As Long,s As ZString Ptr)As ZString Ptr Asm push ebx mov ebx,[esp+8] mov eax,[esp+12] cmp ebx,1024 jge short BC_b1024'число более КB push eax push ebx Call zltoa mov dword Ptr[eax],16928' B add eax,2 pop ebx ret 8
BC_b1024: cmp ebx,1048576 jl Short BC_k cmp ebx,1073741824 jge Short BC_mb Shr ebx,10 mov ecx,4345120' MB jmp Short BC_g BC_k: mov ecx,4344608' KB jmp Short BC_g BC_mb: Shr ebx,20 mov ecx,4343584' GB BC_g: push ecx mov ecx,ebx Shr ecx,10 mov edx,ecx Shl edx,10
Sub ebx,edx mov edi,ebx mov edx,ebx
Shl ebx,6'64 Shl edi,5'32 Shl edx,2 Add ebx,edi Add ebx,edx Shr ebx,10 push ebx
push eax push ecx'целое число Call zltoa pop edx test edx,edx jz Short BC_Ext'нет дробной части cmp edx,10 jge Short BC_t10 mov word Ptr[eax],12334'.0 Add dl,48 mov [eax+2],dl'пишем 1 цифру Add eax,3 jmp Short BC_Ext BC_t10: mov byte Ptr[eax],46'. inc eax push eax push edx'остаток 2 цифры Call zltoa
BC_Ext: pop ecx mov dword Ptr[eax],ecx add eax,3 pop ebx ret 8 End Asm End Function
Function Byteconvert64 naked(b As LongInt,s As ZString Ptr)As ZString Ptr Asm push ebx mov ebx,[esp+12] mov edx,[esp+8] test ebx,ebx jnz Short BC64_h'верхняя половина не пуста cmp edx,0 jl Short BC64_h'число более 2 GB push [esp+16] push edx Call Byteconvert pop ebx ret 12
BC64_h: Shr edx,20'lo Shl ebx,12 Or ebx,edx'eax=Mb
mov ecx,ebx Shr ecx,10 mov edx,ecx Shl edx,10
Sub ebx,edx mov edi,ebx mov edx,ebx
Shl ebx,6'64 Shl edi,5'32 Shl edx,2 Add ebx,edi Add ebx,edx Shr ebx,10
push ebx push [esp+20] push ecx'целое число Call zltoa pop edx test edx,edx jz Short BC64_Ext'нет дробной части cmp edx,10 jge Short BC64_t10 mov word Ptr[eax],12334'.0 Add dl,48 mov [eax+2],dl'пишем 1 цифру Add eax,3 jmp Short BC64_Ext BC64_t10: mov byte Ptr[eax],46'. inc eax push eax push edx'остаток 2 цифры Call zltoa
BC64_Ext: mov dword Ptr[eax],4343584' GB Add eax,3 pop ebx ret 12 End Asm End Function
Function zltoa naked(l As Long,s As ZString Ptr)As ZString Ptr Asm push edi mov eax,[esp+8] mov edi,[esp+12] test eax,eax jz short ZL0 jns short ZLpos mov byte ptr[edi],45'- neg eax inc edi ZLpos: mov ecx,3435973837 push esi mov esi,edi push ebx
cmp eax,1 jl Short ZLendw1 ZLwhile1: mov ebx,eax mul ecx shr edx,3 mov eax,edx lea edx,[edx*4+edx] add edx,edx sub ebx,edx add bl,48'0 mov [edi],bl inc edi cmp eax,0 jg Short ZLwhile1 ZLendw1:
mov byte ptr[edi],0 mov eax,edi cmp esi,edi jge Short ZLendw2 ZLwhile2: dec edi mov cl,[esi]' mov ch,[edi]' mov [edi],cl mov [esi],ch inc esi cmp esi,edi jl Short ZLwhile2 ZLendw2:
pop ebx pop esi pop edi ret 8
ZL0: mov word ptr[edi],48'0 inc edi mov eax,edi pop edi ret 8 End Asm End Function
Сообщение отредактировал Somerick - Воскресенье, 07.08.2016, 06:36 |
|
| |