0

I am converting a bash script to a Qt Qml Felgo app called Galaxy Calculator and I need to calculate the circumference of the Galaxy, Floating Point failed by 100 miles in the calculation, using JavaScript of C++, the numbers are way to big for a long double. This is the bash line

echo "$(bc <<< "scale=13;((241828072282107.5071453596951 * 666) * 2) * 3.14159265359")"

I explain this so you will understand the number, and I do not want to debate the Math, it is part of PhD in Physics, that describes this math, but you can check the results to any estimate of this number, but it is not part of my question, just trying to explain what type of calculations I am doing that requires so much accuracy. When calculating distance in the Galaxy it is going to be a big Number, all I need help with is getting the correct output from multiplying two numbers together, here is my Function:

 QString MathWizard::multiply(const QString &mThis, const QString &mThat)
 {
     using namespace boost::multiprecision;

     cpp_dec_float_100 aThis = mThis.toFloat();
     cpp_dec_float_100 aThat = mThat.toFloat();
     cpp_dec_float_100 ans = (aThis * aThat);

     std::stringstream ss;
     ss.imbue(std::locale(""));
     ss << std::fixed << std::setprecision(16) << ans;

     return QString::fromStdString(ss.str());
 }

Just looking at the code most programmer will notice my first error: toFloat() I pass in strings and return a string to avoid ever having to use a Float, yet I can not find another way to populate this data type, because I have no idea how to pass in a String, I have looked for two days for an example, so that is my first problem, that might be causing my second, which is I am getting a return value of this:

1011954108252979200.000000

when I expected this (bc is great: takes a string, and gives it back);

1011954093357316199.9999999999118107708

Maybe I am being a little picky, the number is very close, but those extra digits are in Miles, Feet and Inches, and this is just one equation, this error will add up the more I do, and this is only one example, some calculations have more math than others, so I need help to figure out how to pass in a String, and how to return a sting with all the Accuracy this function can give me, I can round it later, some I need for other calculations, so I do not want them round more than 16, since after that we are talking about fractions of an inch, and I do not need that much accuracy, but I do need fractional miles, feet down to the last inch.

I did try mpfr_float, and others like it, so I am wondering if it is the fact that I have to convert this to a float that is messing it up; so I really need to be able to fill this value with a string, so I do not lose any precision.

My inputs for this function are in the bash script, I have to do this 3 times to get the answer, and I do not mind that, over using eval to run it, and PI is fixed at that many digits, because that is what my First Cousin many times removed Isaac Newton used in all his calculations, so I can not use PI. I can use any data type that works, and if you know of documents that show how to do this, please include them, links to boost will more than likely been ones I have already read, been a boost user since it first came out, first time I used this Library, but all their examples are the same, and their documentation is very clinical, not in a bad way, you know what I mean, it reads like a computer wrote it, and used one page as a template for the next, so all the docs look the same after a while, a long time grip of mine, I like a lot of examples with every function, and real world applications that show it in use, and I have not found any documents on boost like that, follow this link to see what I mean if you think I am exaggerating or Ranting:

boost: https://www.boost.org/doc/libs/1_68_0/libs/multiprecision/doc/html/index.html

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
user83395
  • 103
  • 1
  • 8
  • They are the numbers from the bash script, I take them in pairs of two, so it takes 3 times to get the answer. – user83395 Mar 29 '19 at 02:22
  • This looks like an X Y problem. Is there a reason why you do not use [gmp](https://gmplib.org/) **everywhere** in the code? What exactly do you hope to achieve manipulating strings? See also [boost/gmp](https://www.boost.org/doc/libs/1_68_0/libs/multiprecision/doc/html/boost_multiprecision/tut/rational/gmp_rational.html) – Patrick Trentin Mar 29 '19 at 03:17
  • I only use MPFR in my functions: add, subtract, multiply and so on, the returned answer goes in a LocalStorage database as TEXT, it is also used to make other calculations, which this class will handle all of them, as such in the code does not need a float, I do all the math with stings, so I do not lose any actuary, and then is displayed in a GridView. – user83395 Mar 29 '19 at 03:25
  • The **gmp** library provides **arbitrary-precision arithmetic**, so there is no need to use `floats`, nor to use `bc`, nor to convert anything to `string`, except for displaying or storing something in a database. *IMHO* this application could benefit from using `mpq_t` or the `boost` equivalent type `mpq_rational`. – Patrick Trentin Mar 29 '19 at 03:28

1 Answers1

1

You do not have to convert the QString to float since cpp_dec_float_100 accepts std::string;

QString MathWizard::multiply(const QString &mThis, const QString &mThat){
    using namespace boost::multiprecision;
    cpp_dec_float_100 aThis(mThis.toStdString());
    cpp_dec_float_100 aThat(mThat.toStdString());
    cpp_dec_float_100 ans = (aThis * aThat);
    return QString::fromStdString(ans.str());
}

Output:

1011954093357316199.999999999911810770784788
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • I knew it took a string, I never thought about having to use toStdString(), I tried without it, and did not think about what type of string it required, thanks, that is the correct answer, now I can finish my program. JavaScript and C++ double, long double and float really opened my eyes, I had no idea they were so wrong, but boost fixed that. – user83395 Mar 29 '19 at 04:05
  • Forgot to check accept, sorry about that, I did remember to check the up arrow, I got half right, just forgot the one under it. – user83395 Mar 30 '19 at 00:14