Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
#1

Случайные числа - C++

19.08.2011, 13:14. Просмотров 1263. Ответов 16
Метки нет (Все метки)

Всем привет! Мне нужно сгенерировать действительное случайное число в диапазоне от нуля до 1. Читал вот это: http://www.cyberforum.ru/cpp-beginners/thread44753.html, но там говорится про целые числа...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.08.2011, 13:14     Случайные числа
Посмотрите здесь:

Случайные числа - C++
Можно ли генерировать случайные числа типа float с помощью rand()?

случайные числа - C++
Всем привет! нужна ваша помощь. мне нужно реализовать функцию, которая заполняет двумерный массив mat случайными числами. на сколько я...

Случайные числа от -8 к 8 - C++
Как можно сделать рандомом числа от -8 к 8, нашел на форуме пример: int r=(rand() % 11) + 5;//от 0 до 10 и +5, то есть от 5 до 15 но...

Случайные числа - C++
Доброго времени суток! Возможно ли сделать так, чтобы выпадали в случайном порядке числа 0, 2, 6, 8?

Случайные числа - C++
Создать матрицу случайных чисел, если max элемент располагается левее минимального то тогда сложить элементы левой половинки матрицы.

Случайные числа - C++
Всем доброго времени суток, я чёт туплю, подскажите, как посчитать сколько чисел сгенерированных случайным образом в диапазоне попадают в...

Случайные числа от -10 до 10 - C++
сижу я значит и не могу вывести случайные числа от -10 до 10! Получается только от -50 до 50, for(int j= 0; j<8; j++) ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Olga_
840 / 182 / 16
Регистрация: 01.08.2011
Сообщений: 502
19.08.2011, 13:19     Случайные числа #2
Так разделите сгенерированное число на длину диапазона, делов то
Например, если ваше число из промежутка от A до B (включительно), то полученное число разделите на (B-A+1)
silent_1991
Эксперт С++
4961 / 3037 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.08.2011, 13:19     Случайные числа #3
C++
1
double rand_value = static_cast< double >(rand()) / RAND_MAX;
lemegeton
2923 / 1352 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
19.08.2011, 13:23     Случайные числа #4
C
1
float n = (rand() % 10000) / 10000.;
Вместо десяти тысяч подставляй любые числа для получения нужной точности.

C
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
 
int main(int argc, char *argv[]) {
  srand(time(NULL));
  int N = 5; // пять знаков после запятой.
  printf("%.10f\n", (rand() % (int)pow(10, N)) / pow(10, N));
 
  return 0;
}
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
19.08.2011, 13:37  [ТС]     Случайные числа #5
Цитата Сообщение от lemegeton Посмотреть сообщение
C
1
float n = (rand() % 10000) / 10000.;
Вместо десяти тысяч подставляй любые числа для получения нужной точности.

C
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
 
int main(int argc, char *argv[]) {
  srand(time(NULL));
  int N = 5; // пять знаков после запятой.
  printf("%.10f\n", (rand() % (int)pow(10, N)) / pow(10, N));
 
  return 0;
}
Это не подойдёт, потому что я посмотрел RAND_MAX = 32768. То есть максимальная точность, которую можно получить это 1/32768.
Olga_
840 / 182 / 16
Регистрация: 01.08.2011
Сообщений: 502
19.08.2011, 13:40     Случайные числа #6
Можно так, если вам одно число надо:

C++
1
    (double)time(NULL)/ULONG_MAX;
grizlik78
Эксперт С++
1908 / 1440 / 110
Регистрация: 29.05.2011
Сообщений: 2,995
19.08.2011, 13:45     Случайные числа #7
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
Это не подойдёт, потому что я посмотрел RAND_MAX = 32768. То есть максимальная точность, которую можно получить это 1/32768.
Возьми генератор, у которого диапазон больше.
В библиотеке GSL широкий выбор генераторов, я бы их использовал.
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
19.08.2011, 14:21  [ТС]     Случайные числа #8
А как её подключить, и где скачать?
grizlik78
Эксперт С++
1908 / 1440 / 110
Регистрация: 29.05.2011
Сообщений: 2,995
19.08.2011, 15:21     Случайные числа #9
Проще всего её использовать в Linux, конечно же.
http://www.gnu.org/software/gsl/
Но и для Windows видел скомпилированные варианты. Правда здесь могут быть и сложности для разных компиляторов.
Иногда недостатком может быть её лицензия — GPL

Добавлено через 29 минут
В принципе можно попробовать скомбинировать случайное число из нескольких
Например так должны получаться числа из диапазона [0, 1) с разрешением примерно в одну миллиардную.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
 
#define RND_BITS 15
#if (1ul << RND_BITS) - 1 != RAND_MAX
#error Wrong value of RND_BITS
#endif
 
#define DBL_SIZE_RAND (( ((long)rand() << RND_BITS) | rand() ) / (double)(1ul << (2*RND_BITS)))
 
int main(void)
{
    double rnd_val;
    srand((unsigned)(time(NULL)));
 
    rnd_val = DBL_SIZE_RAND;
 
    printf("rnd_val: %g\n", rnd_val);
    
    return 0;
}
Но раз требования к ГПСЧ выше, чем к обычному rand(), то я бы всё-таки смотрел на альтернативные генераторы. Если есть сложности с GSL, могу попробовать помочь.
easybudda
Эксперт CЭксперт С++
9470 / 5483 / 927
Регистрация: 25.07.2009
Сообщений: 10,508
19.08.2011, 15:38     Случайные числа #10
Не мудрствуя лукаво (0; 1]
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
    
double drand(void){
    double d = (double)(rand() + 1) / (double)(rand() + 1);
    return d / pow(10.0, ceil(log10(d)));
}
 
int main(void){
    int i;
    
    srand(time(NULL));
    for ( i = 0; i < 10; ++i )
        printf("%f\n", drand());
        
    return 0;
}
grizlik78
Эксперт С++
1908 / 1440 / 110
Регистрация: 29.05.2011
Сообщений: 2,995
19.08.2011, 15:44     Случайные числа #11
Цитата Сообщение от easybudda Посмотреть сообщение
(double)(rand() + 1)
По-моему в этом месте программа сломается, если вдруг RAND_MAX == INT_MAX
Я короче записываю обычно: (rand() + 1.0), хотя и ещё раз к даблу привести не повредит.

Добавлено через 2 минуты
easybudda, а там равномерное распределение получается? Что-то как-то не очевидно.
easybudda
Эксперт CЭксперт С++
9470 / 5483 / 927
Регистрация: 25.07.2009
Сообщений: 10,508
19.08.2011, 15:48     Случайные числа #12
Цитата Сообщение от grizlik78 Посмотреть сообщение
По-моему в этом месте программа сломается, если вдруг RAND_MAX == INT_MAX
Теоритически может, но это какой-то маргинальный случай, обычно там
C
1
#define RAND_MAX    0x7FFF
Если так всего бояться, то можно
C
1
double d = ((double)rand() + 0.1) / ((double)rand() + 0.1);
но я бы не заморачивался...

Добавлено через 1 минуту
Цитата Сообщение от grizlik78 Посмотреть сообщение
а там равномерное распределение получается?
Да чёрт его знает... Можно изменить цикл
C
1
for ( i = 0; i < 100500; ++i )
результат в файл и изучать, что получится. На глаз вроде ничё так последовательности...
grizlik78
Эксперт С++
1908 / 1440 / 110
Регистрация: 29.05.2011
Сообщений: 2,995
19.08.2011, 15:56     Случайные числа #13
Цитата Сообщение от easybudda Посмотреть сообщение
Теоритически может, но это какой-то маргинальный случай, обычно там
Ну значит у меня маргинальный GCC
$ grep RAND_MAX -B1 /usr/include/stdlib.h
/* The largest number rand will return (same as INT_MAX). */
#define RAND_MAX 2147483647
Добавлено через 6 минут
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <assert.h>
 
double drand(void){
    double d = (double)(rand() + 1) / (double)(rand() + 1);
    return d / pow(10.0, ceil(log10(d)));
}
 
#define N 10
 
int main(void){
    int i;
    int cnt[N];
    for ( i = 0; i < N; ++i )
        cnt[i] = 0;
 
    srand(time(NULL));
    for ( i = 0; i < 1000*N; ++i )
    {
        unsigned idx = N*(1.0 - drand());
        assert(idx < N);
        ++cnt[idx];
    }
    for ( i = 0; i < N; ++i )                
        printf("cnt[%d] = %d\n", i, cnt[i]);
    
    return 0;
}
Результат:
cnt[0] = 621
cnt[1] = 607
cnt[2] = 671
cnt[3] = 733
cnt[4] = 707
cnt[5] = 832
cnt[6] = 1027
cnt[7] = 1457
cnt[8] = 3345
cnt[9] = 0
easybudda
Эксперт CЭксперт С++
9470 / 5483 / 927
Регистрация: 25.07.2009
Сообщений: 10,508
19.08.2011, 16:00     Случайные числа #14
Цитата Сообщение от grizlik78 Посмотреть сообщение
Ну значит у меня маргинальный GCC
Да, это я что-то погорячился... Ну тогда ((double)rand() + 0.1). Так вроде бы не должно обнуляться...

200 чисел
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
    
double drand(void){
    double d = ((double)rand() + 0.1) / ((double)(rand() + 0.1));
    return d / pow(10.0, ceil(log10(d)));
}
 
int main(void){
    int i, j;
    
    srand(time(NULL));
    for ( i = 1; i < 201; ++i )
        printf("%.8f%s", drand(), ( i % 6 ) ? "  " : "\n");
        
    return 0;
}

Результат
Код
C:\c_cpp\numbers>gcc -o drand drand.c

C:\c_cpp\numbers>drand
0.13408709  0.45438382  0.20997227  0.28582088  0.47934566  0.70207744
0.80142783  0.11285232  0.10017294  0.32219875  0.14201281  0.21939556
0.72064488  0.71223923  0.66613015  0.83083992  0.34304319  0.47746109
0.12242242  0.52487659  0.94874149  0.25269225  0.22163864  0.63875379
0.22708711  0.12037155  0.38233554  0.21128308  0.83689846  0.99518291
0.32645971  0.17803438  0.33741471  0.43446061  0.10399398  0.33922063
0.30402586  0.72990869  0.38214058  0.12692512  0.37016251  0.16352609
0.42100462  0.97823775  0.23424048  0.42015095  0.44437679  0.12353194
0.14431375  0.60560665  0.11781796  0.13394005  0.44395224  0.62175893
0.81992461  0.83912069  0.26671849  0.65803503  0.44179500  0.35539157
0.48121330  0.54772206  0.14353008  0.52777368  0.15835940  0.23142768
0.16930682  0.12201771  0.70176335  0.13181393  0.19406651  0.98627138
0.14164158  0.71810773  0.26883522  0.28677665  0.18602492  0.12826084
0.89619636  0.69113789  0.11136309  0.32574622  0.11203060  0.93134284
0.94115108  0.23962475  0.16901496  0.12735332  0.31190313  0.21171270
0.13574662  0.69101045  0.45534408  0.29591413  0.38996416  0.10465808
0.14764675  0.84053127  0.24983965  0.38221488  0.16014635  0.91472573
0.11378074  0.36289655  0.62868948  0.11311313  0.39656151  0.97624394
0.10490198  0.42158518  0.14162824  0.47222358  0.11180244  0.13253781
0.65163090  0.15149216  0.77111881  0.10692751  0.22192583  0.79310515
0.10261053  0.83233248  0.11246742  0.66353418  0.57380631  0.14257267
0.12364680  0.10157202  0.43665649  0.66699525  0.40242673  0.78446027
0.17287892  0.35278461  0.30718313  0.71415941  0.85101637  0.10954653
0.90804842  0.22999891  0.94726724  0.69922107  0.57407012  0.73058384
0.45122386  0.93527746  0.23106121  0.44087031  0.49882093  0.64576453
0.56784913  0.12812567  0.42992645  0.37501747  0.22982386  0.94057448
0.76696871  0.39571402  0.62805393  0.84396103  0.91289743  0.11651659
0.27112123  0.21773571  0.95695310  0.14058905  0.27447721  0.25067962
0.71775141  0.33639818  0.10052040  0.66479427  0.17353157  0.22751950
0.81624253  0.11165994  0.65255280  0.29873404  0.23138585  0.77620395
0.13899751  0.12649695  0.11693862  0.31505214  0.17811168  0.26604305
0.37800195  0.81811912  0.12342671  0.16791423  0.28091345  0.18186519
0.64902356  0.16578954  0.11262510  0.17164544  0.17303484  0.13305711
0.35952225  0.15212247
C:\c_cpp\numbers>
далеко, конечно, от идеала, но в принципе в не особо придирчивых приложениях вполне можно пользоваться. За то просто...

Не по теме:

Подошло бы для задания вероятности выйгрыша в одноруком бандите - как-то оно к 0.1 ближе, чем к 1 получается...

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.08.2011, 16:01     Случайные числа
Еще ссылки по теме:

Случайные числа - C++
Привет, мне надо наполнить массив случайными числами но толька чтоб они не повторялись, подскажыте как ето сделать.

случайные числа - C++
как заполнить массив случайными числами например от -50 до 50 void generate(int mas,int n){ for(int i=0;i&lt;n;i++) mas=(rand()%50)-50; ...

случайные числа - C++
подскажите как сформировать двумерный массив случайных чисел в заданном диапозоне которые не повторяются

Случайные числа. - C++
Есть числа 2,4,6,8,0 - из них нужно случайно выбрать одно. Как это сделать? Google'ил, нашел только что то по типу #include &lt;stdlib.h&gt; ...

Случайные числа от 1 до 9 - C++
Можно так создавать случайные числа от 1 до 9 void main() { srand(time(0)); for (int i = 0; i&lt;20; i++) { cout &lt;&lt;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
grizlik78
Эксперт С++
1908 / 1440 / 110
Регистрация: 29.05.2011
Сообщений: 2,995
19.08.2011, 16:01     Случайные числа #15
Ну 1.0 по моему ничем не хуже (хотя, наверное, и не лучше)
Yandex
Объявления
19.08.2011, 16:01     Случайные числа
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru