-
11. Data: 2013-04-08 23:46:11
Temat: Re: zamiana liczby
Od: firr kenobi <p...@g...com>
W dniu poniedziałek, 8 kwietnia 2013 18:46:59 UTC+2 użytkownik identyfikator:
20040501 napisał:
> - w czym problem - nie ma tam dielenia ?
>
>
>
> nie ma, nie chce mi się pisać bo procka sporo zajmie pamięci, dlatego
>
> pytałem czy istnieje lepszy sposób
mozesz zrobic na switchu kombinowanym
z petlami for cos w stylu
if(x>=100 and x<1000)
{
digit_setki=0;
while(x>100)
{
x-=100; digit_setki++;
}
pisz('0'+digit_setki);
}
to samo jeszcze dla dziesiatek
i reszta dla jednostek, jest proste
do napisania i nie takie dlugie
dokladniej nie che mi sie pisac ale
cos takiego powinno chyba dzialac, czy nie ma
lepszego sposobu to nie wiem -
-
12. Data: 2013-04-10 01:18:10
Temat: Re: zamiana liczby
Od: "Ireneusz Szpilewski" <i...@s...opole.pl>
On Sun, 07 Apr 2013 21:17:35 +0200, identyfikator: 20040501
<N...@g...pl> wrote:
> jest taka sprawa, jest sobie liczba dword (32 bity),
> trzeba ją zamienić na skróconą wielkość pliku, np. 100kB, 1Mb, 10Mb,
> 512kB itp...
>
> jak to szybko i skutecznie zrobić?
>
> tricki z dzieleniem przez 10 lub sumowaniem w BCD raczej odpadają, mam
> mało pamięci i do tego rejestry 8 bitowe...
>
> tak w ramach rozrywki umysłowej...
>
> tylko BARDZO UPRZEJMIE PROSZĘ nie flejmować...
>
Takie cos ponizej wysmazylem w ramach rozrywki :-), niestety uzylem
recznego mnozenia 4 znakowej liczby dziesietnej (cos na ksztalt BCD), ale
za to bez dzielenia, no i na samych rejestrach 8 bit powinno zadzialac:
#include <stdio.h>
/* zeruj wynik */
void dec_zero(unsigned char dec[4])
{
int i;
for(i = 0; i < 4; i++)
dec[i] = 0;
}
/* pomnoz wynik razy 2 i dodaj carry (0 lub 1) */
void dec_double(unsigned char dec[4], int carry)
{
int i;
int digit;
for(i = 0; i < 4; i++)
{
digit = dec[i] * 2 + carry;
if(digit > 9)
{
digit -= 10;
carry = 1;
}
else
{
carry = 0;
}
dec[i] = digit;
}
}
/* wylicz wynik result[4] dla podanej liczby number[4] */
/* i zwroc indeks potegi 1024 (0 = B, 1 = KB, 2 = MB, 3 = GB) */
int convert(const unsigned char number[4], unsigned char result[4])
{
int byte = 3;
int bit = 31;
int bit10 = 1;
int power1024 = 3;
unsigned char mask = 0x80;
int hit = 0;
int bit_is_set;
dec_zero(result);
while(bit >= 0)
{
bit_is_set = (number[byte] & mask) != 0;
dec_double(result, bit_is_set);
if(bit_is_set)
{
hit = 1;
}
if(bit10 == 0)
{
if(hit)
return power1024;
bit10 = 9;
power1024--;
}
else
{
bit10--;
}
bit--;
mask >>= 1;
if(mask == 0)
{
mask = 0x80;
byte--;
}
}
return 0;
}
/* drukuj liczbe */
void dec_print(unsigned char dec[])
{
int i;
int print = 0;
for(i = 3; i >= 0; i--)
{
if(print == 0)
print = (dec[i] != 0 || i == 0);
if(print)
printf("%d", (int) dec[i]);
}
}
/* programik testujacy do zabawy*/
int main()
{
unsigned char number[4] = {0, 0, 0, 0};
unsigned char result[4] = {0, 0, 0, 0};
const char* power1024_names[4] = {"B", "KB", "MB", "GB"};
while(1)
{
unsigned try_it;
int power1024;
printf("liczba hex: ");
scanf("%x", &try_it);
printf("liczba dec = %u\n", try_it);
/* katastrofa, jesli unsigned wiekszy niz 4 bajty: */
*(unsigned*)number = try_it;
power1024 = convert(number, result);
printf("wynik = ");
dec_print(result);
printf("%s\n\n", power1024_names[power1024]);
}
return 0;
}
Trzeba by to jeszcze ulepszyc, aby dzialalo sensowniejsze zaokraglanie,
bo teraz zaokragla brutalnie w dol i np. rozmiar 2047 B pokazuje jako 1KB.
Irek
-
13. Data: 2013-04-10 02:19:10
Temat: Re: zamiana liczby
Od: "Borneq" <b...@a...hidden.pl>
Użytkownik "Ireneusz Szpilewski" <i...@s...opole.pl> napisał w
wiadomości news:op.wvaq0ku4wyk85p@localhost...
> Trzeba by to jeszcze ulepszyc, aby dzialalo sensowniejsze zaokraglanie,
> bo teraz zaokragla brutalnie w dol i np. rozmiar 2047 B pokazuje jako 1KB.
Wystarczy dodać najpierw 512. Ale czy na pewno dzielić przez 1024 ?, dla
mnie znacznie wygodniejsze byłoby 1000
-
14. Data: 2013-04-10 11:43:53
Temat: Re: zamiana liczby
Od: firr kenobi <p...@g...com>
W dniu środa, 10 kwietnia 2013 01:18:10 UTC+2 użytkownik Ireneusz Szpilewski napisał:
> On Sun, 07 Apr 2013 21:17:35 +0200, identyfikator: 20040501
>
> <N...@g...pl> wrote:
>
>
>
> > jest taka sprawa, jest sobie liczba dword (32 bity),
>
> > trzeba ją zamienić na skróconą wielkość pliku, np. 100kB, 1Mb, 10Mb,
>
> > 512kB itp...
>
> >
>
> > jak to szybko i skutecznie zrobić?
>
> >
>
> > tricki z dzieleniem przez 10 lub sumowaniem w BCD raczej odpadają, mam
>
> > mało pamięci i do tego rejestry 8 bitowe...
>
> >
>
> > tak w ramach rozrywki umysłowej...
>
> >
>
> > tylko BARDZO UPRZEJMIE PROSZĘ nie flejmować...
>
> >
>
>
>
> Takie cos ponizej wysmazylem w ramach rozrywki :-), niestety uzylem
>
> recznego mnozenia 4 znakowej liczby dziesietnej (cos na ksztalt BCD), ale
>
> za to bez dzielenia, no i na samych rejestrach 8 bit powinno zadzialac:
>
>
>
> #include <stdio.h>
>
>
>
> /* zeruj wynik */
>
> void dec_zero(unsigned char dec[4])
>
> {
>
> int i;
>
>
>
> for(i = 0; i < 4; i++)
>
> dec[i] = 0;
>
> }
>
>
>
> /* pomnoz wynik razy 2 i dodaj carry (0 lub 1) */
>
> void dec_double(unsigned char dec[4], int carry)
>
> {
>
> int i;
>
> int digit;
>
>
>
> for(i = 0; i < 4; i++)
>
> {
>
> digit = dec[i] * 2 + carry;
>
>
>
> if(digit > 9)
>
> {
>
> digit -= 10;
>
> carry = 1;
>
> }
>
> else
>
> {
>
> carry = 0;
>
> }
>
>
>
> dec[i] = digit;
>
> }
>
> }
>
>
>
> /* wylicz wynik result[4] dla podanej liczby number[4] */
>
> /* i zwroc indeks potegi 1024 (0 = B, 1 = KB, 2 = MB, 3 = GB) */
>
> int convert(const unsigned char number[4], unsigned char result[4])
>
> {
>
> int byte = 3;
>
> int bit = 31;
>
> int bit10 = 1;
>
> int power1024 = 3;
>
> unsigned char mask = 0x80;
>
> int hit = 0;
>
> int bit_is_set;
>
>
>
> dec_zero(result);
>
>
>
> while(bit >= 0)
>
> {
>
> bit_is_set = (number[byte] & mask) != 0;
>
>
>
> dec_double(result, bit_is_set);
>
>
>
> if(bit_is_set)
>
> {
>
> hit = 1;
>
> }
>
>
>
> if(bit10 == 0)
>
> {
>
> if(hit)
>
> return power1024;
>
>
>
> bit10 = 9;
>
> power1024--;
>
> }
>
> else
>
> {
>
> bit10--;
>
> }
>
>
>
> bit--;
>
> mask >>= 1;
>
>
>
> if(mask == 0)
>
> {
>
> mask = 0x80;
>
> byte--;
>
> }
>
> }
>
>
>
> return 0;
>
> }
>
>
>
> /* drukuj liczbe */
>
> void dec_print(unsigned char dec[])
>
> {
>
> int i;
>
> int print = 0;
>
>
>
> for(i = 3; i >= 0; i--)
>
> {
>
> if(print == 0)
>
> print = (dec[i] != 0 || i == 0);
>
>
>
> if(print)
>
> printf("%d", (int) dec[i]);
>
> }
>
> }
>
>
>
> /* programik testujacy do zabawy*/
>
> int main()
>
> {
>
> unsigned char number[4] = {0, 0, 0, 0};
>
> unsigned char result[4] = {0, 0, 0, 0};
>
> const char* power1024_names[4] = {"B", "KB", "MB", "GB"};
>
>
>
> while(1)
>
> {
>
> unsigned try_it;
>
> int power1024;
>
>
>
> printf("liczba hex: ");
>
>
>
> scanf("%x", &try_it);
>
> printf("liczba dec = %u\n", try_it);
>
>
>
> /* katastrofa, jesli unsigned wiekszy niz 4 bajty: */
>
> *(unsigned*)number = try_it;
>
>
>
> power1024 = convert(number, result);
>
> printf("wynik = ");
>
> dec_print(result);
>
> printf("%s\n\n", power1024_names[power1024]);
>
> }
>
>
>
> return 0;
>
> }
>
>
>
> Trzeba by to jeszcze ulepszyc, aby dzialalo sensowniejsze zaokraglanie,
>
> bo teraz zaokragla brutalnie w dol i np. rozmiar 2047 B pokazuje jako 1KB.
>
>
co do zaokraglanie w dół to mz chyba ujdzie
co do kodu to nie rozumiem tego kodu, jak to
działa? - jedzie jakos po 32 bitach i co
jakis czas mnozy przez dwa i costam porownuje?
(kod raczej nie jest idealny ale jak działa
to spox,
duzy plus za odpowiedz na temat, bardziej
tak wlasnie widze grupe jako miejsce gdzie
odowiada sie na pytania a nie ... (wiadomo
co )
-
15. Data: 2013-04-10 19:24:51
Temat: Re: zamiana liczby
Od: "Ministerstwo Propagandy" <...@...s>
dobrze powiedziane, niestety oni dostają granty za "wiadomo co"...
-
16. Data: 2013-04-10 21:24:00
Temat: Re: zamiana liczby
Od: "Ireneusz Szpilewski" <i...@s...opole.pl>
On Wed, 10 Apr 2013 02:19:10 +0200, Borneq <b...@a...hidden.pl>
wrote:
> Użytkownik "Ireneusz Szpilewski" <i...@s...opole.pl> napisał w
> wiadomości news:op.wvaq0ku4wyk85p@localhost...
>> Trzeba by to jeszcze ulepszyc, aby dzialalo sensowniejsze zaokraglanie,
>> bo teraz zaokragla brutalnie w dol i np. rozmiar 2047 B pokazuje jako
>> 1KB.
>
> Wystarczy dodać najpierw 512.
Nie bardzo jednak wiem, w ktorym miejscu chcialbys dodac te 512.
Zrobilem za to druga wersje, ktora z kolei zaokragla w gore, czyli np.
1025 pokazuje jako 2KB. To moze byc lepsze w tych przypadkach, gdy chcemy
miec pewnosc, ze plik napewno nie bedzie wiekszy niz ten rozmiar, ktory
podajemy. Ten drugi algorytm latwo przerobic, aby miec to, o co Ci chodzi
z dodawaniem 512 - zaokraglanie do najblizszej liczby, w gore lub w dol.
Tu jest ta nowa wersja;
#include <stdio.h>
/* zeruj wynik */
void dec_zero(unsigned char dec[4])
{
int i;
for(i = 0; i < 4; i++)
dec[i] = 0;
}
/* pomnoz wynik razy factor(1 lub 2) i dodaj carry (0 lub 1) */
void dec_double(unsigned char dec[4], int factor, int carry)
{
int i;
int digit;
for(i = 0; i < 4; i++)
{
digit = factor * dec[i] + carry;
if(digit > 9)
{
digit -= 10;
carry = 1;
}
else
{
carry = 0;
}
dec[i] = digit;
}
}
/* wylicz wynik result[4] dla podanej liczby number[4] */
/* i zwroc indeks potegi 1024 (0 = B, 1 = KB, 2 = MB, 3 = GB) */
int convert(const unsigned char number[4], unsigned char result[4])
{
int byte = 3;
int bit10 = 1;
int power1024 = 3;
unsigned char mask = 0x80;
int hit = 0;
int bit_is_set;
int factor = 2;
dec_zero(result);
while(1)
{
bit_is_set = (number[byte] & mask) != 0;
dec_double(result, factor, bit_is_set);
mask >>= 1;
if(mask == 0)
{
if(byte == 0)
break;
mask = 0x80;
byte--;
}
if(bit_is_set)
{
if(factor == 1)
break;
hit = 1;
}
if(bit10 == 0)
{
if(hit)
{
factor = 1;
bit10--;
}
else
{
bit10 = 9;
power1024--;
}
}
else
{
bit10--;
}
}
if(result[3] == 1 && result[2] == 0 && result[1] == 2 && result[0] == 4)
{
dec_zero(result);
result[0] = 1;
power1024++;
}
return power1024;
}
/* drukuj liczbe */
void dec_print(unsigned char dec[])
{
int i;
int print = 0;
for(i = 3; i >= 0; i--)
{
if(print == 0)
print = (dec[i] != 0 || i == 0);
if(print)
printf("%d", (int) dec[i]);
}
}
/* programik testujacy */
int main()
{
unsigned char number[4] = {0, 0, 0, 0};
unsigned char result[4] = {0, 0, 0, 0};
const char* power1024_names[4] = {"B", "KB", "MB", "GB"};
while(1)
{
unsigned try_it;
int power1024;
printf("liczba hex: ");
scanf("%x", &try_it);
printf("liczba dec = %u\n", try_it);
/* katastrofa, jesli unsigned wiekszy niz 4 bajty: */
*(unsigned*)number = try_it;
power1024 = convert(number, result);
printf("wynik = ");
dec_print(result);
printf("%s\n\n", power1024_names[power1024]);
}
return 0;
}
> Ale czy na pewno dzielić przez 1024 ?, dla mnie znacznie wygodniejsze
> byłoby 1000
No to zalezy, co chcemy osiagnac, czy wynik np. 123 KB ma oznaczac 123 *
1024 bajty po informatycznemu, czy 123 * 1000 bajtow po normalnemu,
(chociaz wtedy raczej pisze sie kB). Jesli to drugie, to algorytm trzeba
by znacznie zmienic.
Irek
--
Using Opera's mail client: http://www.opera.com/mail/
-
17. Data: 2013-04-10 23:23:21
Temat: Re: zamiana liczby
Od: "Ireneusz Szpilewski" <i...@s...opole.pl>
On Wed, 10 Apr 2013 02:19:10 +0200, Borneq <b...@a...hidden.pl>
wrote:
> Użytkownik "Ireneusz Szpilewski" <i...@s...opole.pl> napisał w
> wiadomości news:op.wvaq0ku4wyk85p@localhost...
>> Trzeba by to jeszcze ulepszyc, aby dzialalo sensowniejsze zaokraglanie,
>> bo teraz zaokragla brutalnie w dol i np. rozmiar 2047 B pokazuje jako
>> 1KB.
>
> Wystarczy dodać najpierw 512. Ale czy na pewno dzielić przez 1024 ?, dla
> mnie znacznie wygodniejsze byłoby 1000
Tu jest wersja z kB = 1000B zamiast KB = 1024B, dla prostoty tez zaokragla
w dol:
#include <stdio.h>
/* zeruj wynik */
void dec_zero(unsigned char dec[10])
{
int i;
for(i = 0; i < 10; i++)
dec[i] = 0;
}
/* pomnoz wynik razy 2 i dodaj carry (0 lub 1), *leftmost = najstarsza
cyfra wyniku */
void dec_double(unsigned char dec[10], int carry, int* leftmost)
{
int i;
int digit;
for(i = 0; i < *leftmost; i++)
{
digit = 2 * dec[i] + carry;
if(digit > 9)
{
digit -= 10;
carry = 1;
}
else
{
carry = 0;
}
dec[i] = digit;
}
if(carry)
{
dec[i] = 1;
(*leftmost)++;
}
}
/* wylicz wynik result[10] dla podanej liczby number[4] */
/* i zwroc najstarsza cyfre wyniku (liczona od 1)) */
int convert(const unsigned char number[4], unsigned char result[10])
{
int byte = 3;
unsigned char mask = 0x80;
int bit_is_set;
int leftmost = 1;
dec_zero(result);
while(1)
{
bit_is_set = (number[byte] & mask) != 0;
dec_double(result, bit_is_set, &leftmost);
mask >>= 1;
if(mask == 0)
{
if(byte == 0)
break;
mask = 0x80;
byte--;
}
}
return leftmost;
}
/* drukuj wynik */
void dec_print(unsigned char dec[10], int leftmost, const char*
power1000_names[4])
{
int power = (leftmost - 1) / 3;
int count = leftmost - power * 3;
int i;
for(i = 1; i <= count; i++)
{
printf("%d", (int) dec[leftmost - i]);
}
printf(power1000_names[power]);
}
/* programik testujacy */
int main()
{
unsigned char number[4] = {0, 0, 0, 0};
unsigned char result[10];
const char* power1000_names[4] = {"B", "kB", "MB", "GB"};
while(1)
{
unsigned try_it;
int leftmost;
printf("liczba: ");
scanf("%u", &try_it);
/* katastrofa, jesli unsigned wiekszy niz 4 bajty: */
*(unsigned*)number = try_it;
leftmost = convert(number, result);
printf("wynik = ");
dec_print(result, leftmost, power1000_names);
printf("\n\n");
}
return 0;
}
Irek
--
Using Opera's mail client: http://www.opera.com/mail/
-
18. Data: 2013-04-10 23:52:43
Temat: Re: zamiana liczby
Od: firr kenobi <p...@g...com>
W dniu środa, 10 kwietnia 2013 19:24:51 UTC+2 użytkownik Ministerstwo Propagandy
napisał:
> dobrze powiedziane, niestety oni dostają granty za "wiadomo co"...
haha :-) !
-
19. Data: 2013-04-11 11:25:49
Temat: Re: zamiana liczby
Od: "R.e.m.e.K" <g...@d...null>
Dnia Wed, 10 Apr 2013 21:24:00 +0200, Ireneusz Szpilewski napisał(a):
>>> Trzeba by to jeszcze ulepszyc, aby dzialalo sensowniejsze zaokraglanie,
>>> bo teraz zaokragla brutalnie w dol i np. rozmiar 2047 B pokazuje jako
>>> 1KB.
>>
>> Wystarczy dodać najpierw 512.
>
> Nie bardzo jednak wiem, w ktorym miejscu chcialbys dodac te 512.
Chyba mial na mysli, ze do wartosci poczatkowej. Jesli masz 2047 i pokazuje
1KB to po dodaniu 512 bedzie 2559 i pokaze juz 2KB. Czyli te 512
"wysrodkuje" zakres w polowie 1025 i ponizej bedzie rownac w dol a powyzej w
gore. Tak czy nie? :-)
--
pozdro
R.e.m.e.K
-
20. Data: 2013-04-12 17:45:19
Temat: Re: zamiana liczby
Od: "Ireneusz Szpilewski" <i...@s...opole.pl>
W dniu 11.04.2013 o 11:25 R.e.m.e.K <g...@d...null> pisze:
> Dnia Wed, 10 Apr 2013 21:24:00 +0200, Ireneusz Szpilewski napisał(a):
>
>>>> Trzeba by to jeszcze ulepszyc, aby dzialalo sensowniejsze
>>>> zaokraglanie,
>>>> bo teraz zaokragla brutalnie w dol i np. rozmiar 2047 B pokazuje jako
>>>> 1KB.
>>>
>>> Wystarczy dodać najpierw 512.
>>
>> Nie bardzo jednak wiem, w ktorym miejscu chcialbys dodac te 512.
>
> Chyba mial na mysli, ze do wartosci poczatkowej. Jesli masz 2047 i
> pokazuje
> 1KB to po dodaniu 512 bedzie 2559 i pokaze juz 2KB. Czyli te 512
> "wysrodkuje" zakres w polowie 1025 i ponizej bedzie rownac w dol a
> powyzej w
> gore. Tak czy nie? :-)
No właśnie nie bardzo, bo to jest lekarstwo na zaokrąglanie w ramach KB, a
co dla MB i GB?
Np. dla liczby 2096639, która powinna być zaokrąglona do 2 MB?
Irek
--
Używam klienta poczty Opera Mail: http://www.opera.com/mail/