According to wikipedia, the layouts of the different precision data types are
- single precision: exponent (e): 8 bits, fraction (f): 23 bits
- double precision: e: 11 bits, f: 52 bits
- quadruple precision: e: 15 bits, f: 112 bits.
I wrote a small program to output the numerical limits for float, double and long double in C++ (compiled with g++)
#include<iostream>
#include<limits>
#include<string>
template<typename T>
void print(std::string name) {
std::cout << name << " (" << sizeof(T) * 8 << "): " << std::numeric_limits<T>::epsilon() << "\t" << std::numeric_limits<T>::min() << "\t" << std::numeric_limits<T>::max() << std::endl;
}
int main() {
std::cout.precision(5);
print<float>("float");
print<double>("double");
print<long double>("long double");
return 0;
}
which outputs (I have run it on multiple machines with the same result)
float (32): 1.1921e-07 1.1755e-38 3.4028e+38
double (64): 2.2204e-16 2.2251e-308 1.7977e+308
long double (128): 1.0842e-19 3.3621e-4932 1.1897e+4932
The upper limits coincide with 2^(2^(e-1)) and for float and double, epsilon coincides with 2^(-f). For long double, however epsilon should be roughly 1.9259e-34 by that logic.
Does anyone know, why it isn't?