2015-07-06 11:59:37 +02:00

134 lines
3.1 KiB
C

/*
# float.h
Gives characteristics of floating point numbers and of base numerical operations
for the current architecture
All macros that start with FLT have versions starting with:
- DBL for `double`
- LDBL for `long double`
*/
#include "common.h"
int main() {
/*
# Rounding method
# FLT_ROUNDS
Rounding method of sums.
Values:
- -1: indeterminable
- 0: toward zero
- 1: to nearest
- 2: toward positive infinity
- 3: toward negative infinity
TODO can it be changed?
*/
{
printf("FLT_ROUNDS = %d\n", FLT_ROUNDS);
}
/*
# FLT_MIN
Smalles positive number closest to zero that can be represented in a normal float.
Any number with absolute value smaller than this is subnormal,
and support is optional.
*/
{
printf("FLT_MIN = %a\n", FLT_MIN);
printf("DBL_MIN = %a\n", DBL_MIN);
printf("LDBL_MIN = %La\n", LDBL_MIN);
}
/*
# FLT_RADIX
Radix of the mantissa.
TODO wow, there are non radix 2 representation implementations?!
IEEE 754 specifies the 2015-hardware-lowly-implemented radix 10,
maybe that is the major motivation?
# FLT_MANT_DIG
Number of digits bits for the mantissa:
- 24 on 32-bit float
# FLT_MANT_DIG
*/
{
printf("FLT_RADIX = %d\n", FLT_RADIX);
printf("FLT_MANT_DIG = %d\n", FLT_MANT_DIG);
}
#if __STDC_VERSION__ >= 201112L
/*
# subnormal numbers
C11
Defined in IEC 60599.
E.g.:
0.01
Is represented as:
1 * 10^-2
However the exponent has a fixed number of bits, so if the exponent is too small.
A solution to incrase that exponent is to allow number that start with 0.
So if for example -4 is the smallest possible exponent, 10^-5 could be represented as:
0.1 * 10^-4
Such a number that cannot be represented without trailling zeroes is a subnormal number.
The tradeoff is that subnormal numbers have limited precision.
C11 specifies that the implementation of this feature is optional,
and oe can check if those are supported in the implementation via the `HAS_SUBNORM` macros.
As of 2013 hardware support is low but starting to appear.
Before this date, implementations are done on software, and are therefore slow.
The smallest floating normal number is `FLT_MIN`.
Values:
- -1: undeterminable
- 0: no
- 1: yes
*/
{
printf("FLT_HAS_SUBNORM = %d\n", FLT_HAS_SUBNORM);
printf("DBL_HAS_SUBNORM = %d\n", DBL_HAS_SUBNORM);
printf("LDBL_HAS_SUBNORM = %d\n", LDBL_HAS_SUBNORM);
assert(isnormal(LDBL_MIN));
if (LDBL_HAS_SUBNORM) {
long double ldbl_min_2 = LDBL_MIN / 2.0;
printf("LDBL_MIN / 2.0 = %La\n", ldbl_min_2);
assert(ldbl_min_2 != 0);
assert(ldbl_min_2 != LDBL_MIN);
assert(! isnormal(ldbl_min_2));
}
}
#endif
return EXIT_SUCCESS;
}