C++ with Qt - Conversion of angle in radians to DDD°MM′SS.FFF″ string
Nice code - easy to read and well laid out.  No surprises in the code, apart from the need to clear up the carry from seconds to minutes etc.

Some small improvements:


Although M_PI is in POSIX, if you want to be properly portable, you'll want to define your own π, perhaps as 4*std::atan(1.);
You might help the compiler to hoist the value of 180/PI if you re-write the multiplication as angleInRad*(180/PI) or 180/PI*angleInRad.
There's no checking that the degrees value is in range of int when casting.
It might make more sense to represent the angle in seconds or minutes rather than degrees (compromising the range in exchange for easier handling of the modular arithmetic).


My version

#include &lt;QString&gt;

#include &lt;climits&gt;
#include &lt;cmath&gt;

QString radians_to_dms(double radians, int precision)
{
    static const double PI = 4*std::atan(1.);

    if (std::abs(radians) &gt; ULONG_MAX*PI/180/60)
        // out of range
        return "---";

    const auto total_minutes = std::abs(radians*(60*180/PI));
    auto whole_minutes = static_cast&lt;int&gt;(total_minutes);
    auto seconds = 60 * (total_minutes - whole_minutes);

    auto secStr = QString::number(seconds, 'f', precision);
    if (secStr.startsWith("60")) {
        // it rounds up - carry to minutes
        secStr = QString::number(0.0, 'f', precision);
        whole_minutes += 1;
    } else if (secStr.startsWith('-')) {
        // negative zero - shouldn't happen
        secStr = QString::number(0.0, 'f', precision);
    }
    if (secStr.size() &lt; 2 || secStr[1] == '.')
        // zero-fill
        secStr.prepend('0');

    return QString::fromUtf8(u8"%1%2°%3′%4″")
        .arg(radians &lt; 0 ? "-" : "")
        .arg(whole_minutes / 60, 3, 10, QChar('0'))
        .arg(whole_minutes % 60, 2, 10, QChar('0'))
        .arg(secStr);
}




#include &lt;QDebug&gt;
int main()
{
    for (double a: { -0.0, -3.1415926535897932384, 1.0,
                     59.999996/3600*4*std::atan(1.)/180,
                     1. * ULONG_MAX})
        qDebug() &lt;&lt; a &lt;&lt; " = " &lt;&lt; qPrintable(radians_to_dms(a, 5));

    const double step = .000142857;
    for (double a = 0;  a &lt; 10*step;  a+= step)
        qDebug() &lt;&lt; a &lt;&lt; " = " &lt;&lt; qPrintable(radians_to_dms(a, 5));
}


I get reasonable output from the test cases:

0  =  000°00′00.00000″
-3.14159  =  -180°00′00.00000″
1  =  057°17′44.80625″
0.000290888  =  000°01′00.00000″
1.84467e+19  =  ---
0  =  000°00′00.00000″
0.000142857  =  000°00′29.46637″
0.000285714  =  000°00′58.93274″
0.000428571  =  000°01′28.39911″
0.000571428  =  000°01′57.86549″
0.000714285  =  000°02′27.33186″
0.000857142  =  000°02′56.79823″
0.000999999  =  000°03′26.26460″
0.00114286  =  000°03′55.73097″
0.00128571  =  000°04′25.19734″
0.00142857  =  000°04′54.66371″


I'm not sure whether it's much improvement over the original, but I hope it gives you some ideas.