I can not understand how to make the random number generator to give fractional values. I tried to do so. A = rand() % 158.691+(-1.235);

Did not work out. The interval between -1.235 and 157.456.

 #include <iostream> #include <cmath> #include <iomanip> using namespace std; int main() { int N,M; int max = 157456, min = -1235; cout << "Enter size of matrix A:N " << endl; cin >> M; cout << "Enter size of matrix A:M " << endl; cin >> N; cout << "Creating matrix A:" << endl; // Создаётся матрица A float **A = new float* [M]; srand(time(NULL)); int i = 0; do { A[i] = new float [N]; i++; } while(i<N); int j = 0; do { do { float float k = rand(); k = k%(max - min) + min; //double результат = (double)число / (double)1000; A[i][j] = (float)k/(float)1000;; cout << setw(10) << A[i][j]; i++; } while(i<M); j++; cout << endl; } while(j<N); cout << endl << endl; // Освобождение памяти for (int i = 0; i < N; i ++) delete [] A[i]; delete [] A; system("pause"); return 0; } 
  • float float?)) - Max Zhukov
  • 2
    Well, at least that is what long long is, and float float is not - DreamChild
  • one
    > Of course, I understand that you can write your own, and you cannot immediately include them in the library? @AQZ you say so offended about this, as if someone here present is the developer of the standard of this language. For very newbies, there are languages ​​simpler - C ++ is not for those who are looking for everything ready, and you have stumbled over the place that many people pass by without noticing. Further to your surprise there will be no limit. Well, shovel a little bit of all sorts of things - it won't hurt a newcomer, believe me - DreamChild
  • one
    @manking, at least in the fact that the float is now meaningless and more inhibitory than double. There is an opinion that modern processors natively work with double - in the sense that they have registers of the same bitness. Tea, programs not on 386 will be started. - gecube
  • one
    @manking, float - yes small. And the point is still in the implicit conversions in the transmission in the parameters and confusion with the input formats. In general, without much need for saving memory (if accuracy allows) it is better to use double everywhere. Of course, not to replace integers (char, short, int, long ...). - Pro performance. If they say without guile, it is usually about double. Sometimes specify. The fact is that with some processors, performance with a single point (float) is twice as high as with a double. But, this is usually for vector commands (in graph maps, for example). - avp

5 answers 5

In fact, everything is simple.

 // Генерирует случайное действительное число от 0 до 1 (double)(rand())/RAND_MAX // Генерирует случайное действительное число от 0 до N (double)(rand())/RAND_MAX * N 

Here is an example:

 #include <stdlib.h> #include <time.h> #include <iostream> using namespace std; // Функция, генерирующая случайное действительное число от min до max double random(double min, double max) { return (double)(rand())/RAND_MAX*(max - min) + min; } int main() { srand((unsigned int)time(0)); cout << random(-1.235, 157.456) << endl; return 0; } 

Here is the check.

  • one
    @ Sergey Pestov, just one remark. In * nix, the random() function is defined in stdlib.h (although it has a different prototype). / * These are the functions that actually do things. The random', srandom', initstate' and setstate' functions are those of BSD Unices. The rand' and srand' functions are required by the ANSI standard. We provide both interfaces to the same random number generator. * / This example in C ++ will work (and in C it will not compile), but still it is better not to call its functions that way. - avp 9:01 pm
  • @VladD, you do not take into account the fact that division occurs, which will surely fill all the bits of the double mantissa. - Mencey
  • @avp, you are right: rnd.c: 5: 8: error: conflicting types for 'random' /usr/include/stdlib.h:327:17: note: jence
  • @ Sergey Pestov: I'm not talking about that a bit. Bits will be filled, no questions. But if int , for example, is four-bit, then after dividing you will receive no more than 256 ^ 4 different values. Since a double is 8 bytes long, it can take about 256 ^ 8 different values ​​(minus 2 ^ 11 values ​​for infinity and NaN). See the problem? - VladD
  • one
    In addition, I just made a mistake in the formula. RAND_MAX should be squared. - In fact, the topic of pseudorandom numbers is quite complicated. If you need good results, then she seriously need to deal with. - avp

All of the above methods are reduced to approximately one formula:

 res = min + (max - min) / RAND_MAX * rand(); 

There may be problems if the number of significant digits in RAND_MAX less than in the mantissa of the resulting type. This can happen even if res is of type float ( RAND_MAX not always equal to INT_MAX , but it can be much less). It is possible that otherwise, with the distribution of something will be wrong, I can not say for sure.


Therefore, it can not but rejoice that the developers of the standard took care of us and added a new module < random > to the standard library.

 #include <iostream> #include <random> #include <chrono> int main() { const double from = -1.235; const double to = 157.456; using namespace std::chrono; std::default_random_engine engine( system_clock::to_time_t(system_clock::now())); std::uniform_real_distribution<> distr(from, to); auto gen_number = [&engine, &distr] () { return distr(engine); }; for (int i = 0; i < 50; ++i) { std::cout << gen_number() << std::endl; } } 
  • Or, if without an abundance of extra letters, then #include <iostream> #include <random> #include <time.h> using namespace std; int main () {double from = -1.235; double to = 157.456; default_random_engine engine (time (0)); uniform_real_distribution <> myrandom (from, to); for (int i = 0; i <50; ++ i) cout << myrandom (engine) << endl; } IMHO looks less intimidating. - avp
  • @avp, but you mix the time function with pluses, which is also not very good. - ReklatsMasters

Is this how it works?

 double мин = -1.235; double макс = 157.456; int мин__ = (int)(мин*1000); int макс__ = (int)(макс*1000); long long число = rand(); число = число%(макс__ - мин__) + мин__; double результат = (double)число / (double)1000; std::cout << "\nрезультат=" << результат; 

Check:

 for(int i = 0; i < 1000000; i++) { int min = -1235; int max = 157456; // srand(наносекунды); long long D = rand(); D = D%(max - min) + min; double result = (double)D / (double)1000; if(result < -1.235) { std::cout << "\nменьше=" << result; } if(result > 157.456) { std::cout << "\nбольше=" << result; } } 

@ Here is your code.

 #include <iostream> #include <cmath> #include <iomanip> using namespace std; int main(){ int N,M; int max = 157456, min = -1235; cout << "Enter size of matrix A:N " << endl; cin >> M; cout << "Enter size of matrix A:M " << endl; cin >> N; cout << "Creating matrix A:" << endl; // Создаётся матрица A float **A = new float* [M]; srand(time(NULL)); int i = 0; do { A[i] = new float [N]; i++; } while(i<M); int j = 0; // Здесь обнулить счётчик i i = 0; do { do { int k = rand(); k = k%(max - min) + min; //double результат = (double)число / (double)1000; A[i][j] = (float)k/(float)1000;; cout << setw(10) << A[i][j]; i++; } while(i<M); // Здесь еще раз обнулить счётчик i i=0; j++; cout << endl; } while(j<N); cout << endl << endl; // Освобождение памяти for (int i = 0; i < M; i ++) delete [] A[i]; delete [] A; system("pause"); } 

// update the seed once a second srand (seconds);

alt text

// update the seed 1000 times per second srand (milliseconds); alt text

// update seed 1,000,000 times per second srand (microseconds);

alt text

// update the seed 1,000,000,000 times per second srand (nanoseconds);

alt text

Pixel view:

Seconds:

alt text

Milliseconds:

alt text

Microseconds:

alt text

Nanoseconds:

alt text

  • It produces the following type conversion errors: 1> c: \ documents and settings \ 1 \ my documents \ visual studio 2010 \ projects \ lab5 \ lab5.cpp (28): warning C4244: initialization: converting "int" to "float", possible data loss 1> c: \ documents and settings \ 1 \ my documents \ visual studio 2010 \ projects \ lab5 \ lab5.cpp (29): error C2296:%: invalid, left operand is of type "float" - AQZ
  • Warning removed. And where do you have error C2296:%: unacceptable, the left operand is of type "float" Did you copy or rewrite the code? Show the code itself. - manking
  • Well, in the conditions of the task it is said what to do using do .. while You can certainly tell the teacher that the condition of the problem is incorrectly set. With a square array, everything is fine. For different values ​​of M and N, an error occurs. - AQZ
  • @AQZ fixed again. Your memory is allocated to M, you fill it in with N. Delete with N. - manking
 srand(time(NULL)); double a = (double)(rand()%10000); 

well, respectively, add the term-factors to maintain the required range

    I'm not sure that I calculated the numbers correctly, so if such a solution fits, please check it yourself, so that it would give you the numbers you need.

     #include <iostream> #include <ctime> #include <cstdlib> int main() { srand(time(0)); double result; int celoe = 0, drobi = 0, znak = 0; char buff[10]; znak = rand() % 2; // 1 buff[0] = znak ? ' ' : '-'; if (buff[0] == '-') { // 2 celoe = rand() % 2; // Генерирует от 0 до 1 drobi = rand() % 236; // Генерирует от 0 до 235 sprintf(&buff[1], "%d.%d", celoe, drobi); // 4 } else { //3 celoe = rand() % 158; // Генерирует от 0 до 157 drobi = rand() % 457; // Генерирует от 0 до 456 sprintf(buff, "%d.%d", celoe, drobi); // 4 } result = atof(buff); // 5 std::cout << result << "\n"; // 6 system("pause"); return 0; } 
    1. We generate a number from 0 to 1 which will determine the sign of the future fractional number.
    2. We check if our number is negative, then we generate values ​​from a range of numbers that can be included in a negative fractional number.
    3. Well, if the number is positive, then for positive we generate numbers from the range you need.
    4. Here we create a string with a fractional number from the resulting numbers.
    5. We convert a string with a number into a double
    6. Display the result

    PS People, if there is a simple way to generate fractional values, then unsubscribe, maybe it’s in vain that I’ve spent so much time on the city looking))

    And you can make a separate function and when you call a function, transfer the necessary ranges and get the result.

     #include <iostream> #include <ctime> #include <cstdlib> double generate(int min_celoe, int min_drobi, int max_celoe, int max_drobi) { double result; int celoe = 0, drobi = 0, znak = 0; char buff[10]; znak = rand() % 2; buff[0] = znak ? ' ' : '-'; if (buff[0] == '-') { celoe = rand() % (min_celoe + 1); drobi = rand() % (min_drobi + 1); sprintf(&buff[1], "%d.%d", celoe, drobi); } else { celoe = rand() % (max_celoe + 1); drobi = rand() % (max_drobi + 1); sprintf(buff, "%d.%d", celoe, drobi); } result = atof(buff); return result; } int main() { srand(time(0)); double results[100]; for (int i = 0; i < 100; i++) { results[i] = generate(1, 235, 157, 456); std::cout << results[i] << "\n"; } system("pause"); return 0; } 
    • so why don't you like my version?) - Max Zhukov
    • one
      It seems like my decision does not relate to yours in any way. You simply generate a random number from 0 to 9999. - Roman Goriachevskiy
    • A good idea. High quality. I'll try. - AQZ