TTMath is a handy programming library implementing multiple precision floating point numbers on personal computers using C++ (GCC and Visual Studio). It is available as a header-only library, with liberal BSD license allowing free use in professional (commercial) applications without requiring distribution of source code.
Optional assembly language functions are included, which would require linking to a single file. This article shows how to use TTMath as a header-only library that does not require linking.
TTMath is easy to set up, and the progressive source code license allows you to change the library, without requiring original or adapted source code to be distributed.
In this article, we show how to quickly set up and use TTMath, without requiring any kind of configuration settings. Most applications only need this much. If all you need is to get multiple precision numbers implemented in a hurry, this article accomplishes doing that.
After completing this article, advanced users who need more features can then move on to implementing their own functions, for example rounding, elementary functions, etc.
We begin by calculating the sine of
Create a C++ console application, and replace the source code in main.cpp with this source code:
#define TTMATH_NOASM
#include <ttmath/ttmath.h>
#include <iostream>
typedef ttmath::Big<TTMATH_BITS(64),
TTMATH_BITS(128)> MyBig;
int main()
{
MyBig bigfloat_pi, bigfloat_OneFourth,
bigfloat_PiDiv4,bigfloat_sin45;
bigfloat_pi.SetPi();
bigfloat_OneFourth = "0.25";
bigfloat_PiDiv4
= bigfloat_pi * bigfloat_OneFourth;
bigfloat_sin45 = Sin(bigfloat_PiDiv4);
std::cout << "bigfloat_sin45 = "
<< bigfloat_sin45 << std::endl;
}
This calculates the sine of
On x64 systems, used in these examples,
the exponent and mantissa each need
to be a multiple of
Build and run the program, and use a calculator
to verify that the calculated sine of
Problem:
For hot desert sand that is effectively flat
(having enough concave curvature to
offset Earth's convex curvature),
with air temperature within
Answer: We find the critical angle of total internal reflection using Snells Law, and use trigonometry and geometry to calculate horizontal distances from the viewer to the critical angle reflection point, and from the reflection point to the top of the building, as follows:
The NIST Calculator gives these refractive indexes of air at 10 percent relative humidity with light that would have 633 nm wavelength in a vacuum:
35°C n1 = 1.000258339
44°C n2 = 1.000250873
Snells Law states:
\[ \frac{\sin(\theta_1)}{\sin(\theta_2)} = \frac{n_2}{n_1} \]
The angle
θ1
subtends the vertical surface normal
and incidence angle in medium
n1
(35°C air).
The other angle
(θ2)
is the refraction angle
transmitting into medium
n2
(44°C air) and will be
Since
θ2
becomes
sin(θ2) = sin(π/2) = 1
Then Snells Law formula becomes:
\[ \frac{\sin(\theta_1)}{\sin(\theta_2)} = \frac{\sin(\theta_1)}{1} = \sin(\theta_1) = \frac{n_2}{n_1} \]
\[ \theta_1 = \arcsin\left(\frac{n_2}{n_1}\right) \]
Using TTMath to calculate θ1:
#define TTMATH_NOASM
#include <ttmath/ttmath.h>
#include <iostream>
typedef ttmath::Big<TTMATH_BITS(64),
TTMATH_BITS(128)> MyBig;
int main()
{
MyBig n1, n2, n2divn1, theta1,
num2pi, num360, theta1degrees;
n1 = "1.000258339";
n2 = "1.000250873";
n2divn1 = n2 / n1;
theta1 = ASin(n2divn1);
num2pi.Set2Pi();
num360 = "360.0";
theta1degrees
= theta1 * num360 / num2pi;
std::cout
<< "Critical angle in degrees = "
<< std::endl
<< theta1degrees
<< std::endl;
}
gives the following result:
Critical angle in degrees =
89.77862641266625173821492140070866017
That is almost 90° (referred to as grazing incidence).
Next we use the trigonometry of a right triangle to calculate the horizontal distance from the viewer to the vertical surface normal at the critical angle reflection point.
Assume the viewpoint height is
In the following right triangle, used for illustration, vertex A of the triangle is the critical angle reflection point (on the interface between the air layers), C is the viewpoint (at viewer eye level), and AB is the vertical height from the critical angle reflection point to the viewer eye level:
The critical angle of θ is 89.7786264… degrees. The vertical distance from the air layers interface to eye level (AB) is 1.2 meters.
From trigonometry, in a right triangle, for an angle that is not the right angle, the tangent of the angle equals the length of the side opposite the angle divided by the length of the adjacent side that is not the hypotenuse. In this case:
\[ \tan(\theta) = \frac{BC}{AB} \]
The horizontal distance from the viewpoint to surface normal of the critical angle reflection point is BC. Rearranging this formula to solve for BC:
\[ BC = AB \tan(\theta) \]
Using TTMath to calculate BC:
MyBig AB, BC;
AB = "1.2";
BC = AB * Tan(theta1);
std::cout
<< "BC = " << BC
<< " meters"
<< std::endl;
gives the following result:
BC = 310.5817370318422769378978492342740621 meters
Light from the building reaching a reflection point will have the same surface normal angle as its reflection toward the viewer. That angle is denoted θ.
Even though both angles are equal, the distance from the building to the reflection point is longer than from the viewer to the reflection point, because the building is taller than the viewer:
Vertex E of the left triangle is the top of the building,
which has a vertical height of 7 meters above ground level.
Subtracting 30 cm for the warmer air layer at the ground,
the top of the building is 6.7 meters above the
reflecting interface between the two air layers.
This vertical height
Since the two triangles are similar triangles, corresponding ratios of corresponding sides are equal:
\[ \frac{AB}{BC} = \frac{AD}{DE} \]
Rearranging to solve for DE:
\[ DE = \frac{(AD)(BC)}{AB} \]
Using TTMath to calculate DE:
MyBig AD, DE;
AD = "6.7";
DE = (AD * BC) / AB;
std::cout
<< "DE = " << DE
<< " meters"
<< std::endl;
std::cout
<< "BC + DE = " << BC + DE
<< " meters"
<< std::endl;
gives the following result:
DE = 1734.0813650944527129032629915580301799 meters
BC + DE = 2044.663102126294989841160840792304242 meters
The building needs to be at least 2.045 kilometers away.