logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C] Funkcja RAND Jak losuje?

xamrex 15 Mar 2011 21:41 3619 10
REKLAMA
  • #1 9281483
    xamrex
    Poziom 28  
    Witam,
    Naskrobałem sobie coś takiego:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W pliku stdlib.h mam
    #define	RAND_MAX 0x10


    A mimo tego na wyświetlaczu pojawia mi się liczba 167, dlaczego?
  • REKLAMA
  • #2 9281743
    michalko12
    Specjalista - Mikrokontrolery
    Jak rand liczy to dowiesz się z źródła:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #3 9281775
    xamrex
    Poziom 28  
    Rozumiem, z tego, że liczy sobie jakąś liczbę potem robi z tego modulo RAND_MAX+1.

    Ale jeśli moje RAND_MAX jest 10, to nie powinienem dostać wyniku większego od 10..
  • #4 9281813
    KwoiteK
    Poziom 16  
    Dlaczego tak jest to trzeba pytać google lub szukać lub szukać w kodach .


    Jeśli poza tym jak to działa zależy Ci co zrobić żeby działało poprawnie to polecam taki zapis:

    wylosowana=(uint8_t)(rand() % 0x10);


    wylosowana będzie wynosić od 0 do 0x0F


    Pozdrawiam.
  • #5 9281828
    michalko12
    Specjalista - Mikrokontrolery
    xamrex napisał:
    Rozumiem, z tego, że liczy sobie jakąś liczbę potem robi z tego modulo RAND_MAX+1.

    Ale jeśli moje RAND_MAX jest 10, to nie powinienem dostać wyniku większego od 10..


    Sprawdź
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    i nie 10 a 16 (0x10)
  • #6 9281959
    xamrex
    Poziom 28  
    michalko12 dalej Wyświetla 167 ;/ (nawet jak w tym pliku stdlib.h zmienię
    #define	RAND_MAX 0x22

    na coś innego)
    KwoiteK wiem jak wylosować losową liczbę (ja do tego celu używam timera i potem robię modulo)
  • REKLAMA
  • Pomocny post
    #7 9282068
    michalko12
    Specjalista - Mikrokontrolery
    Generalnie w samym stdlib.h nie powinieneś nic zmieniać. Możesz jeszcze wyświetlić dla pewności RAND_MAX, ale i tak dziwne jest to, że ciągle otrzymujesz tą sama wartość. W przerwaniach dodaj funkcje srand() żeby zmieniało się ziarno. Sama funkcja rand() jest już skompilowana do postaci biblioteki i zmiana RAND_MAX nic już nie da.
  • #8 9282974
    hotdog
    Poziom 26  
    Ogólnie aby mieć dobrą pseudolosowość, to musisz pociągnąć jakieś dane z otoczenia. Np jak masz jakiś przycisk to zmierz czas od startu programu do jego przyciśnięcia i później długość jego trzymania. Wartości najlepiej potraktuj jakąś funkcją mieszającą (jakiś prosty hash), żeby miała duży rozkład. Dalej opracuj jakąś funkcję pseudolosową na podstawie seeda wyliczonego z tych 2 zmiennych.

    Możesz do tego też wykorzystać jakieś adc, temperaturę, RTC czy cokolwiek, czas do odebrania pierwszego znaku przez UART itd.

    Bez takich mechanizmów, jeżeli masz program z wyświetlaczem i LCD zawsze będziesz miał te same wartości - co włączenie zasilania.
  • REKLAMA
  • #9 9283031
    pol1111
    Poziom 12  
    michalko12 napisał:
    Generalnie w samym stdlib.h nie powinieneś nic zmieniać. Możesz jeszcze wyświetlić dla pewności RAND_MAX, ale i tak dziwne jest to, że ciągle otrzymujesz tą sama wartość. W przerwaniach dodaj funkcje srand() żeby zmieniało się ziarno. Sama funkcja rand() jest już skompilowana do postaci biblioteki i zmiana RAND_MAX nic już nie da.


    W tym że to jest zawsze ta sama liczba to nie ma nic dziwnego. Przecież program jest deterministyczny, więc póki nie odbiera żadnych sygnałów zewnętrznych to każde wywołanie musi się skończyć tak samo.

    Dlatego tak jak przedmówcy wspomnieli, żeby uzyskać jakąkolwiek losowość to ziarno musi być uzależnione od jakiegoś sygnału zewnętrznego (najłatwiej spróbkować na starcie jakiś przetwornik adc wiszący w powietrzu)
  • #10 9283074
    michalko12
    Specjalista - Mikrokontrolery
    pol1111 napisał:
    michalko12 napisał:
    Generalnie w samym stdlib.h nie powinieneś nic zmieniać. Możesz jeszcze wyświetlić dla pewności RAND_MAX, ale i tak dziwne jest to, że ciągle otrzymujesz tą sama wartość. W przerwaniach dodaj funkcje srand() żeby zmieniało się ziarno. Sama funkcja rand() jest już skompilowana do postaci biblioteki i zmiana RAND_MAX nic już nie da.


    W tym że to jest zawsze ta sama liczba to nie ma nic dziwnego. Przecież program jest deterministyczny, więc póki nie odbiera żadnych sygnałów zewnętrznych to każde wywołanie musi się skończyć tak samo.


    Nie każde, tylko każde pierwsze, następne powinny być już inne ale nadal seriami takie same i dlatego napisałem żeby w przerwaniach dodał funkcję srand();
  • #11 9283373
    xamrex
    Poziom 28  
    Mi nie chodzi o wylosowanie LOSOWEJ liczby, bo wiem jak moża coś takiego zrobić nie używając w ogóle funkcji rand();
    -Można zrobić to na timerze
    -lub za pomocą diody (mierzyć jej napięcie)

    Chce się dowiedzieć, czemu jak wpisuje w programie funkcję rand(); to mimo ustalonego zakresu w pliku stdlib.h
    #define RAND_MAX 0x22


    Wyświetla mi się liczba 167
REKLAMA