FreeBasic
Главная
Вход
Регистрация
Среда, 16.10.2024, 08:13Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
ConvertBytes
electrikДата: Пятница, 23.10.2015, 21:50 | Сообщение # 1
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: 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
Репутация: 2
Статус: 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
 
electrikДата: Пятница, 24.03.2017, 01:26 | Сообщение # 3
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: Offline
Спасибо, эти функции тоже полезные!
 
  • Страница 1 из 1
  • 1
Поиск: