eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programmingzamiana liczbyRe: zamiana liczby
  • Path: news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!news.cyf-kr.edu.pl!news.task
    .gda.pl!not-for-mail
    From: "Ireneusz Szpilewski" <i...@s...opole.pl>
    Newsgroups: pl.comp.programming
    Subject: Re: zamiana liczby
    Date: Wed, 10 Apr 2013 21:24:00 +0200
    Organization: CI TASK http://www.task.gda.pl/
    Lines: 210
    Message-ID: <op.wvcauawgwyk85p@localhost>
    References: <kjsgog$lu7$1@node2.news.atman.pl> <op.wvaq0ku4wyk85p@localhost>
    <kk2b5u$k5s$1@node1.news.atman.pl>
    NNTP-Posting-Host: 178.252.26.75.internetia.net.pl
    Mime-Version: 1.0
    Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes
    Content-Transfer-Encoding: Quoted-Printable
    X-Trace: news.task.gda.pl 1365621833 2715 178.252.26.75 (10 Apr 2013 19:23:53 GMT)
    X-Complaints-To: a...@n...task.gda.pl
    NNTP-Posting-Date: Wed, 10 Apr 2013 19:23:53 +0000 (UTC)
    User-Agent: Opera Mail/12.14 (Linux)
    Xref: news-archive.icm.edu.pl pl.comp.programming:202539
    [ ukryj nagłówki ]

    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/

Podziel się

Poleć ten post znajomemu poleć

Wydrukuj ten post drukuj


Następne wpisy z tego wątku

Najnowsze wątki z tej grupy


Najnowsze wątki

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: