Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
36 / 29 / 2
Регистрация: 01.08.2011
Сообщений: 176
1

Случайные числа

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

Всем привет! Мне нужно сгенерировать действительное случайное число в диапазоне от нуля до 1. Читал вот это: https://www.cyberforum.ru/cpp-... 44753.html, но там говорится про целые числа...
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.08.2011, 13:14
Ответы с готовыми решениями:

Нужно чтобы случайные числа вставали в конец массива,а не удаляли числа
#include <iostream> using namespace std; void main() { setlocale(LC_ALL, "Russian"); int n;...

случайные числа
rand() в VS имеет диапазон от 0 до 32768? даже изменение RAND_MAX ничего не повысит верхний уровень?

Случайные числа
Необходимо написать программу, которая будет генерировать случайную величину от 0 до 1 (включая 0 и...

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

16
847 / 189 / 18
Регистрация: 01.08.2011
Сообщений: 505
19.08.2011, 13:19 2
Так разделите сгенерированное число на длину диапазона, делов то
Например, если ваше число из промежутка от A до B (включительно), то полученное число разделите на (B-A+1)
0
Эксперт С++
5037 / 3097 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
19.08.2011, 13:19 3
C++
1
double rand_value = static_cast< double >(rand()) / RAND_MAX;
0
3052 / 1457 / 492
Регистрация: 29.11.2010
Сообщений: 2,888
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;
}
0
36 / 29 / 2
Регистрация: 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.
0
847 / 189 / 18
Регистрация: 01.08.2011
Сообщений: 505
19.08.2011, 13:40 6
Можно так, если вам одно число надо:

C++
1
    (double)time(NULL)/ULONG_MAX;
0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
19.08.2011, 13:45 7
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
Это не подойдёт, потому что я посмотрел RAND_MAX = 32768. То есть максимальная точность, которую можно получить это 1/32768.
Возьми генератор, у которого диапазон больше.
В библиотеке GSL широкий выбор генераторов, я бы их использовал.
0
36 / 29 / 2
Регистрация: 01.08.2011
Сообщений: 176
19.08.2011, 14:21  [ТС] 8
А как её подключить, и где скачать?
0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
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, могу попробовать помочь.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
10855 / 6729 / 1616
Регистрация: 25.07.2009
Сообщений: 12,469
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;
}
0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
19.08.2011, 15:44 11
Цитата Сообщение от easybudda Посмотреть сообщение
(double)(rand() + 1)
По-моему в этом месте программа сломается, если вдруг RAND_MAX == INT_MAX
Я короче записываю обычно: (rand() + 1.0), хотя и ещё раз к даблу привести не повредит.

Добавлено через 2 минуты
easybudda, а там равномерное распределение получается? Что-то как-то не очевидно.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
10855 / 6729 / 1616
Регистрация: 25.07.2009
Сообщений: 12,469
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 )
результат в файл и изучать, что получится. На глаз вроде ничё так последовательности...
0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
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
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
10855 / 6729 / 1616
Регистрация: 25.07.2009
Сообщений: 12,469
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 получается... :)

0
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
19.08.2011, 16:01 15
Ну 1.0 по моему ничем не хуже (хотя, наверное, и не лучше)
0
36 / 29 / 2
Регистрация: 01.08.2011
Сообщений: 176
20.08.2011, 20:12  [ТС] 16
Вот так можно сгенерировать случайные числа с большой точностью:
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
32
33
34
35
36
37
38
39
40
41
// Test.cpp : Defines the entry point for the console application.
 
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
using namespace std;
 
#define fl float
#define du double
#define ld long double
#define si short int
#define li long int
#define usi unsigned short int
#define uli unsigned long int
#define uint unsigned int
 
inline fl randf()
{
    fl rndM=(fl)RAND_MAX;
    fl res=0;
    for (fl rests=1.f-1.f/rndM;rests>0;rests/=rndM)
    {
        res+=((fl)rand()/rndM)*rests;
    }
    return res;
}
 
int _tmain(int argc, _TCHAR* argv[])
{   
    srand((uint)time(NULL));
    si kol;
    cin>>kol;
    for (;kol>0;kol--)
    {
        cout<<randf()<<'\n';
        system("pause");
    }
    system("pause");
    return 0;
}
1
Эксперт С++
2137 / 1568 / 239
Регистрация: 29.05.2011
Сообщений: 3,261
20.08.2011, 20:39 17
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
Вот так можно сгенерировать случайные числа с большой точностью:
Вряд ли термин точность хорошо подходит к случайным числам
По сути это тот же подход, что и использованный мной в #9, только с другой стороны и гораздо хитрее
Только всё-равно хочется предупредить — несмотря на то, что два случайных числа теперь могут получиться гораздо ближе друг к другу, нежели при простом делении на RAND_MAX, тем не менее разнообразие этих чисел может оказаться недостаточным из-за ограниченного внутреннего состояния ГПСЧ. Так что получаемые числа всё-равно надо проверять на удовлетворение неким требованиям. А для получения чисел с достаточным разрешением желательно использовать генераторы с по возможности большим размером внутреннего состояния.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.08.2011, 20:39

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Случайные числа
Написать функцию, которая подсчитует сколько раз заданое число встречается в последовательности N...

Случайные числа.
Есть числа 2,4,6,8,0 - из них нужно случайно выбрать одно. Как это сделать? Google'ил, нашел...

Случайные числа
Кто знает, как получить случайное число (отдельно для целого и дробного) от 0 до n, причем чтобы от...

случайные числа
как заполнить массив случайными числами например от -50 до 50 void generate(int mas,int n){...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

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