Hello all,

I haven't used c++ for years and now I need it for school. I am running a fortran 77 code and I wanted to know if it is possible to write a program in c++ (That's the only language I know) that generates random numbers with decimals and creates a file with the output in the form below. Where the bold letters are each separate random numbers in a certain range.


JUPITER m=X r=3.d0 d=depends on X
Y U O
A S W

0. 0. 0.
SATURN m=V r=3.d0 d=depends on V
M C Q
D N P
0. 0. 0.

I don't have my C++ books anymore so I don't have a resource to look at other than the internet, and I don't know if this is very ambitious. Any input would be great, thank you for you time. :)

Dani AI

Generated

Short answer: yes — a small C++ program can generate the floating-point values and write them into a file in exactly the layout shown by . ’s reminder about seeding and formatting is useful, but a modern, more robust approach is to use C++11’s <random> for generation and <iomanip> for Fortran-like formatting.

Plan of action:

  • Pick a generator (e.g., std::mt19937_64) and either a deterministic seed (for repeatability) or std::random_device for nondeterministic runs.
  • Use std::uniform_real_distribution<double> (or other distributions) to produce values in the required ranges for mass, positions, velocities.
  • Format numbers with std::scientific, std::uppercase and std::setprecision(17) to match the many significant digits in the example. If the Fortran code expects a “D” exponent (double literal), convert the formatted string’s ‘E’ to ‘D’ before writing.
  • Write blocks to file with std::ofstream using the same whitespace/line breaks as the Fortran input.

Example (concise) — generates two planet blocks and writes them to a file:

#include <fstream>
#include <random>
#include <iomanip>
#include <sstream>
#include <string>

std::string fmt_fortran(double v, bool useD=true) {
  std::ostringstream ss;
  ss << std::uppercase << std::scientific << std::setprecision(17) << v;
  std::string s = ss.str();
  if (useD) for (char &c : s) if (c=='E') c='D';
  return s;
}

int main() {
  std::mt19937_64 rng(123456789); // replace with std::random_device{}() to vary runs
  std::uniform_real_distribution<double> mass(1e-6,1e-3), pos(-20.0,20.0), vel(-1e-2,1e-2);
  std::ofstream out("random_input.dat");
  for (auto name : {"JUPITER","SATURN"}) {
    double m = mass(rng);
    out << name << "    m=" << fmt_fortran(m) << " r=3.d0 d=1.00\n";
    out << fmt_fortran(pos(rng)) << " " << fmt_fortran(pos(rng)) << " " << fmt_fortran(pos(rng)) << "\n";
    out << fmt_fortran(vel(rng)) << " " << fmt_fortran(vel(rng)) << " " << fmt_fortran(vel(rng)) << "\n";
    out << "0. 0. 0.\n";
  }
}

Troubleshooting notes: if Fortran uses formatted reads with fixed widths, add std::setw to match column widths. To replicate an exact run, store and reuse the RNG seed. If the Fortran reader fails on ‘E’ exponents, enable the conversion to ‘D’ as shown.

Recommended Answers

All 3 Replies

Can you be more specific?

I guess what I'm asking is I'm not sure how to have a random number generator that places the values it comes up with in the places where the bold letters are in my previous message. From the random number generators I have seen you compile them and they create an executable that has the random numbers, what I need is a file that is created with the random numbers already places where the bold letters are. Ultimately this file will be used by the fortran code and this is what it looks like as it is...

JUPITER m=9.54791938424326609E-04 r=3.d0 d=1.33
4.84143144246472090E+00 -1.16032004402742839E+00 -1.03622044471123109E-01
1.66007664274403694E-03 7.69901118419740425E-03 -6.90460016972063023E-05

0. 0. 0.
SATURN m=2.85885980666130812E-04 r=3.d0 d=0.70
8.34336671824457987E+00 4.12479856412430479E+00 -4.03523417114321381E-01
-2.76742510726862411E-03 4.99852801234917238E-03 2.30417297573763929E-05

0. 0. 0.

but instead of using these bold values, I need random values, and need them written out to a file similar to that above. I hope I have made myself clear. Thanks.

Use #include <cstdlib> at the top of your program, and then use srand once to seed the random number generator. Then use rand() to produce a random number between zero and RAND_MAX. Use some math to scale the random number to the range you want.

You might want to try to get larger initial random integers by using (rand() * RAND_MAX + 1)) + rand() and scale those numbers to the range of doubles that you want.

Then use cout with setprecision to output the values. Here's a link to the functions described in a reference.

http://www.fortran-2000.com/ArnaudRecipes/Cstd/2.13.html#rand

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.