Вот более простое решение, отлично работает в моем приложении.
public class MyActivity extends Acitivity {
TextView myTextView;
boolean someCondition=true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
myTextView = (TextView) findViewById(R.id.refreshing_field);
//starting our task which update textview every 1000 ms
new RefreshTask().execute();
}
//class which updates our textview every second
class RefreshTask extends AsyncTask {
@Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
String text = String.valueOf(System.currentTimeMillis());
myTextView.setText(text);
}
@Override
protected Object doInBackground(Object... params) {
while(someCondition) {
try {
//sleep for 1s in background...
Thread.sleep(1000);
//and update textview in ui thread
publishProgress();
} catch (InterruptedException e) {
e.printStackTrace();
};
return null;
}
}
}
rand()
может использоваться для генерации псевдослучайных чисел в C ++. В сочетании с RAND_MAX
и небольшой математикой вы можете генерировать случайные числа в любом произвольном интервале, который вы выберете. Этого достаточно для учебных целей и игрушечных программ. Если вам нужны действительно случайные числа с нормальным распределением, вам нужно будет использовать более продвинутый метод.
Это приведет к генерации числа от 0.0 до 1.0 включительно.
float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
Это приведет к генерации числа от 0.0 до некоторого произвольного float
, X
:
float r2 = static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/X));
. Это приведет к генерации числа от некоторого произвольного LO
до некоторые произвольные HI
:
float r3 = LO + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(HI-LO)));
Обратите внимание, что функция rand()
часто бывает недостаточной, если вам нужны действительно случайные числа.
Перед вызовом rand()
, вы должны сначала «засеять» генератор случайных чисел, вызвав srand()
. Это нужно делать один раз во время запуска вашей программы - не каждый раз, когда вы вызываете rand()
. Это часто делается следующим образом:
srand (static_cast <unsigned> (time(0)));
Для вызова rand
или srand
вы должны #include <cstdlib>
.
Чтобы позвонить time
, вы должен #include <ctime>
.
В современных c++
вы можете использовать заголовок <random>
, который появился с c++11
. Чтобы получить случайные float
, вы можете использовать std::uniform_real_distribution<>
.
Вы можете использовать функцию для генерации чисел, и если вы не хотите, чтобы числа были одинаковыми все время, установите двигатель и распределение будут static
. Пример:
float get_random()
{
static std::default_random_engine e;
static std::uniform_real_distribution<> dis(0, 1); // rage 0 - 1
return dis(e);
}
Идеально разместить float
в контейнере, таком как std::vector
:
int main()
{
std::vector<float> nums;
for (int i{}; i != 5; ++i) // Generate 5 random floats
nums.emplace_back(get_random());
for (const auto& i : nums) std::cout << i << " ";
}
Пример вывода:
0.0518757 0.969106 0.0985112 0.0895674 0.895542
Полностью случайное действительное число с плавающей точкой генерируется следующим образом: случайный знак, случайный показатель и случайная мантисса. Ниже приведен пример генерации случайных чисел из 0..MAXFLOAT с равномерным распределением:
static float frand(){
float f;
UINT32 *fi = (UINT32*)&f;
*fi = 0;
const int minBitsRandGives = (1<<15); // RAND_MAX is at least (1<<15)
UINT32 randExp = (rand()%254)+1; // Exponents are in range of [1..254]
UINT32 randMantissa = ((rand() % minBitsRandGives) << 8) | (rand()%256);
*fi = randMantissa | (randExp<<23); // Build a float with random exponent and random mantissa
return f;
}
Важное примечание: RAND_MAX по умолчанию равно 2 ^ 16 (в 32 битовых системах), поэтому rand () может генерировать не более 15 случайных бит. Поскольку с плавающей запятой имеется всего 32 бита, мы должны активировать rand () не менее 3 раз для генерации случайных 32 бит. Я использовал 8 бит rand () для генерации Exponent и еще 2 вызова rand () для генерации 23 бит мантиссы.
Общая ошибка, которой следует избегать: если вы используете (float)rand()/MAX_RAND
для получения плавающей запятой в range [0..1], вы все равно получите случайные числа в равномерном распределении, но с низкой точностью. Например, ваш случайный генератор может генерировать 0,00001 и 0,00002, но не может генерировать 0,000017. Такое случайное число в 256 раз меньше, чем фактическое представление с плавающей запятой.
Оптимизация. Моя функция не оптимизирована для скорости. Вы можете улучшить его, заменив разделение «%» на побитовые логические операции. Например, вместо %256
используйте &0xFF
До сих пор я не был удовлетворен ни одним из ответов, поэтому написал новую функцию случайного поплавка. Он делает побитовые предположения о типе данных float. Ему по-прежнему нужна функция rand () с не менее 15 случайными битами.
//Returns a random number in the range [0.0f, 1.0f). Every
//bit of the mantissa is randomized.
float rnd(void){
//Generate a random number in the range [0.5f, 1.0f).
unsigned int ret = 0x3F000000 | (0x7FFFFF & ((rand() << 8) ^ rand()));
unsigned short coinFlips;
//If the coin is tails, return the number, otherwise
//divide the random number by two by decrementing the
//exponent and keep going. The exponent starts at 63.
//Each loop represents 15 random bits, a.k.a. 'coin flips'.
#define RND_INNER_LOOP() \
if( coinFlips & 1 ) break; \
coinFlips >>= 1; \
ret -= 0x800000
for(;;){
coinFlips = rand();
RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP();
//At this point, the exponent is 60, 45, 30, 15, or 0.
//If the exponent is 0, then the number equals 0.0f.
if( ! (ret & 0x3F800000) ) return 0.0f;
RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP();
RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP();
RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP();
RND_INNER_LOOP(); RND_INNER_LOOP(); RND_INNER_LOOP();
}
return *((float *)(&ret));
}
drand48(3)
является стандартным способом POSIX. GLibC также предоставляет реентерабельную версию, drand48_r(3)
.
Функция была объявлена устаревшей в SVID 3, но адекватная альтернатива не была предоставлена, поэтому IEEE Std 1003.1-2013 по-прежнему включает в себя и не имеет никаких заметок о том, что в любом случае это произойдет в ближайшее время.
В Windows стандартным способом является CryptGenRandom () .
rand () возвращает int между 0 и RAND_MAX. Чтобы получить случайное число между 0.0 и 1.0, сначала введите int return by rand () в float, а затем разделите на RAND_MAX.
На некоторых системах (в настоящее время Windows с VC наводит на мысль,] RAND_MAX
смехотворно мала, i. е. всего 15 бит. При делении на RAND_MAX
вы генерируете мантиссону из 15 бит вместо 23 возможных бит. Это может быть или не быть проблемой для вас, но в этом случае вы упускаете некоторые значения.
О, только что заметил, что для этой проблемы уже есть комментарий. В любом случае, вот какой код, который может решить это для вас:
float r = (float)((rand() << 15 + rand()) & ((1 << 24) - 1)) / (1 << 24);
Не проиндексирован, но может работать: -)
Если вы знаете, что ваш формат с плавающей запятой - IEEE 754 (почти все современные процессоры, включая Intel и ARM), то вы можете построить случайное число с плавающей запятой из случайного целого с использованием битовых методов. Это следует учитывать только в том случае, если у вас нет доступа к C ++ 11 random
или Boost.Random
, которые намного лучше.
float rand_float()
{
// returns a random value in the range [0.0-1.0)
// start with a bit pattern equating to 1.0
uint32_t pattern = 0x3f800000;
// get 23 bits of random integer
uint32_t random23 = 0x7fffff & (rand() << 8 ^ rand());
// replace the mantissa, resulting in a number [1.0-2.0)
pattern |= random23;
// convert from int to float without undefined behavior
assert(sizeof(float) == sizeof(uint32_t));
char buffer[sizeof(float)];
memcpy(buffer, &pattern, sizeof(float));
float f;
memcpy(&f, buffer, sizeof(float));
return f - 1.0;
}
Это даст лучшее распределение, чем использование деления.
return (float)random23 / (1 << 23)
. (Да, я просто проверил это , изменив вашу функцию, чтобы принять random32
в качестве параметра и запустить его для всех значений от нуля до (1 << 23)-1
. И да, ваш метод действительно дает точно те же результаты, что и деление на 1 << 23
.)
– Ilmari Karonen
3 January 2016 в 17:19
Если вы используете C ++, а не C, помните, что в техническом отчете 1 (TR1) и в проекте C ++ 0x они добавили возможности для генератора случайных чисел в заголовочном файле, я считаю, что он идентичен библиотека Boost.Random и определенно более гибкая и «современная», чем функция библиотеки C, rand.
Этот синтаксис предлагает возможность выбора генератора (например, mersenne twister mt19937 ), а затем выберите распределение (normal, bernoulli, binomial и т. д.).
Синтаксис выглядит следующим образом (бесстыдно заимствовано из этого сайта ):
#include <iostream>
#include <random>
...
std::tr1::mt19937 eng; // a core engine class
std::tr1::normal_distribution<float> dist;
for (int i = 0; i < 10; ++i)
std::cout << dist(eng) << std::endl;
Взгляните на Boost.Random . Вы можете сделать что-то вроде этого:
float gen_random_float(float min, float max)
{
boost::mt19937 rng;
boost::uniform_real<float> u(min, max);
boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > gen(rng, u);
return gen();
}
Поиграйте, вы можете лучше пройти один и тот же объект mt19937, а не конструировать новый каждый раз, но, надеюсь, вы получите эту идею.
max
, но вы можете использовать открытый min
, вы можете легко изменить интервал: return min + max - gen();
.
– Mark Ransom
19 March 2015 в 22:22
Для C ++ он может генерировать реальные числа с плавающей запятой в пределах диапазона, указанного переменной dist
#include <random> //If it doesnt work then use #include <tr1/random>
#include <iostream>
using namespace std;
typedef std::tr1::ranlux64_base_01 Myeng;
typedef std::tr1::normal_distribution<double> Mydist;
int main() {
Myeng eng;
eng.seed((unsigned int) time(NULL)); //initializing generator to January 1, 1970);
Mydist dist(1,10);
dist.reset(); // discard any cached values
for (int i = 0; i < 10; i++)
{
std::cout << "a random value == " << (int)dist(eng) << std::endl;
}
return (0);
}
randMToN
PLS? либо отметьте, что это [M,N]
или добавьте + 1.
из выше randZeroToOne
. - & GT; подумайте, чтобы называть это следующим образом: randMToN(0.0, 1.0);
– BeyelerStudios
1 April 2016 в 07:51
(N-M)
. Хороший способ справиться с этой ошибкой можно найти здесь: stackoverflow.com/questions/33058848/…
– Dr Beco
26 May 2018 в 04:42
На мой взгляд, вышеупомянутый ответ действительно дает некоторый «случайный» float, но ни один из них не является поистине случайным поплавком (т. е. они пропускают часть представления float). Прежде чем я буду спешить с моей реализацией, сначала рассмотрим стандартный формат ANSI / IEEE для float:
| sign (1-bit) | e (8 бит) | f (23-бит) |
число, представленное этим словом, равно (-1 * sign) * 2 ^ e * 1.f
отметить, что число «e» равно (с смещением 127), таким образом, варьируя от -127 до 126. Самая простая (и фактически самая случайная) функция состоит в том, чтобы просто записать данные случайного int в поплавок, таким образом
int tmp = rand();
float f = (float)*((float*)&tmp);
обратите внимание, что если вы сделаете float f = (float)rand();
, он преобразует целое число в float (таким образом, 10 станет 10.0). Итак, если вы хотите ограничить максимальное значение, вы можете сделать что-то вроде (не уверен, что это работает)
int tmp = rand();
float f = *((float*)&tmp);
tmp = (unsigned int)f // note float to int conversion!
tmp %= max_number;
f -= tmp;
, но если вы посмотрите на структуру поплавка, вы увидите, что максимальное значение float (приблизительно) 2 ^ 127, который больше, чем максимальное значение int (2 ^ 32), таким образом исключая значительную часть чисел, которые могут быть представлены поплавком. Это моя окончательная реализация:
/**
* Function generates a random float using the upper_bound float to determine
* the upper bound for the exponent and for the fractional part.
* @param min_exp sets the minimum number (closest to 0) to 1 * e^min_exp (min -127)
* @param max_exp sets the maximum number to 2 * e^max_exp (max 126)
* @param sign_flag if sign_flag = 0 the random number is always positive, if
* sign_flag = 1 then the sign bit is random as well
* @return a random float
*/
float randf(int min_exp, int max_exp, char sign_flag) {
assert(min_exp <= max_exp);
int min_exp_mod = min_exp + 126;
int sign_mod = sign_flag + 1;
int frac_mod = (1 << 23);
int s = rand() % sign_mod; // note x % 1 = 0
int e = (rand() % max_exp) + min_exp_mod;
int f = rand() % frac_mod;
int tmp = (s << 31) | (e << 23) | f;
float r = (float)*((float*)(&tmp));
/** uncomment if you want to see the structure of the float. */
// printf("%x, %x, %x, %x, %f\n", (s << 31), (e << 23), f, tmp, r);
return r;
}
с использованием этой функции randf(0, 8, 0)
вернет случайное число между 0.0 и 255.0
int e = (rand() % (max_exp - min_exp)) + min_exp_mod;
и мантиссы: int f = (int)(frac_mod * (float)rand() / RAND_MAX);
заменяют их соответствующие строки выше. Обратите внимание, что ошибка мантиссы важна: для RAND_MAX
меньше 1 << 23
вы только рандомизировали младшие значащие биты и получали 0s для самых значительных бит все время!
– BeyelerStudios
1 April 2016 в 08:42
Вызвать код с двумя значениями float
, код работает в любом диапазоне.
float rand_FloatRange(float a, float b)
{
return ((b - a) * ((float)rand() / RAND_MAX)) + a;
}
fmaf()
(или перегрузка float fma()
в C ++) на C99 или C ++ 11, что может сохранить более высокую точность. Как и в fmaf((float)rand() / RAND_MAX, b - a, a)
.
– Tim Čas
9 August 2017 в 01:14
rand()
. Этот вопрос и мой ответ были специально сосредоточены на изучении основ и не были связаны с высокой степенью точности. Вы должны научиться ходить, прежде чем научиться бегать. – John Dibling 14 August 2014 в 13:22