Floating-point math (math.h)¶
Include math.h. The DCC C Compiler has only 32-bit float (no double), so
the math entry points are the single-precision ...f variants. The unsuffixed
C89 names are provided as macro aliases for convenience.
Standard C names¶
The standard C89 math names are provided as function-like macros that call the
corresponding single-precision ...f runtime function.
| Name | Meaning |
|---|---|
acos |
Single-precision alias for acosf. |
asin |
Single-precision alias for asinf. |
atan |
Single-precision alias for atanf. |
atan2 |
Single-precision alias for atan2f. |
ceil |
Single-precision alias for ceilf. |
cos |
Single-precision alias for cosf. |
cosh |
Single-precision alias for coshf. |
dcc_nan |
IEEE-754 quiet NaN. Unlike INFINITY, this has no spelling as a numeric literal token, so it is a real extern float object (defined in DCCRTL.MAC) rather than a constant expression: usable in ordinary expressions and local initializers, but NOT in a static/global initializer. |
exp |
Single-precision alias for expf. |
fabs |
Single-precision alias for fabsf. |
floor |
Single-precision alias for floorf. |
fmod |
Single-precision alias for fmodf. |
frexp |
Single-precision alias for frexpf. |
HUGE_VAL |
Value returned on overflow; equals FLT_MAX (dcc has no double). |
HUGE_VALF |
C99 float-flavored HUGE_VAL; true IEEE-754 infinity, unlike HUGE_VAL. |
INFINITY |
IEEE-754 positive infinity, as a genuine compile-time constant: dcc's float-literal parser hands the source text to the host's atof(), and 1e40 already exceeds FLT_MAX, so the host overflows it to (double) infinity before it's narrowed to float. No runtime code, no RTL linkage; usable anywhere a float constant expression is, including static initializers. |
ldexp |
Single-precision alias for ldexpf. |
log |
Single-precision alias for logf. |
log10 |
Single-precision alias for log10f. |
modf |
Single-precision alias for modff. |
pow |
Single-precision alias for powf. |
sin |
Single-precision alias for sinf. |
sinh |
Single-precision alias for sinhf. |
sqrt |
Single-precision alias for sqrtf. |
tan |
Single-precision alias for tanf. |
tanh |
Single-precision alias for tanhf. |
Functions¶
| Function | Summary |
|---|---|
float acosf(float x) |
Arc cosine of x. |
float asinf(float x) |
Arc sine of x. |
float atan2f(float y, float x) |
Arc tangent of y / x using the signs of both arguments. |
float atanf(float x) |
Arc tangent of x. |
float ceilf(float x) |
Round toward positive infinity. |
float cosf(float x) |
Cosine of x, in radians. |
float coshf(float x) |
Hyperbolic cosine. |
float expf(float x) |
Base-e exponential, e raised to x. |
float fabsf(float x) |
Absolute value. |
float floorf(float x) |
Round toward negative infinity. |
float fmodf(float x, float y) |
Floating-point remainder of x / y. |
float frexpf(float x, int *eptr) |
Split x into a normalized fraction and exponent. |
int isfinite(float x) |
True if x is neither NaN nor +/-Inf. |
int isinf(float x) |
True if x is +Inf or -Inf. |
int isnan(float x) |
True if x is a NaN (quiet or signaling). |
float ldexpf(float x, int n) |
Compute x multiplied by 2 raised to n. |
float log10f(float x) |
Base-10 logarithm. |
float logf(float x) |
Natural logarithm, base e. |
float modff(float x, float *iptr) |
Split x into integer and fractional parts. |
float nextafterf(float x, float y) |
Next representable value after x in the direction of y. |
float powf(float x, float y) |
x raised to the power y. |
int signbit(float x) |
True if x's sign bit is set (negative, including -0.0 and -NaN). |
float sinf(float x) |
Sine of x, in radians. |
float sinhf(float x) |
Hyperbolic sine. |
float sqrtf(float x) |
Square root. |
float tanf(float x) |
Tangent of x, in radians. |
float tanhf(float x) |
Hyperbolic tangent. |
Runtime model¶
DCC C Compiler treats float as the only floating type. C89 normally declares the
unsuffixed math names (sqrt, sin, pow, and so on) as double functions,
but this runtime has no double, so math.h maps those names to
the single-precision ...f functions with macros.
Float is the biggest size lever
A single float operator links the shared normalise/round core, and the
transcendental functions (expf/logf/powf and the trig/hyperbolic
families) are the heaviest individual features in the runtime. They are
software routines on the Z80, not hardware floating-point operations, so
budget both code size and execution time. See the
appendix.
Function groups¶
The functions follow the conventional C math families, with single-precision types throughout:
- Rounding, remainder, and roots:
fabsf,floorf,ceilf,fmodf,sqrtf,nextafterf. - Exponential and logarithmic:
expf,logf,log10f,powf. - Trigonometric:
sinf,cosf,tanf,asinf,acosf,atanf,atan2f. - Hyperbolic:
sinhf,coshf,tanhf. - Decomposition:
frexpf,ldexpf,modff.
For portable C89 source, the unsuffixed aliases let familiar calls use the same
single-precision runtime functions. For example, sqrt(x) expands to
sqrtf(x), and atan2(y, x) expands to atan2f((y), (x)).
#include <math.h>
float distance(float dx, float dy)
{
return sqrtf(dx * dx + dy * dy);
}
float heading(float y, float x)
{
return atan2f(y, x);
}
Printing floats¶
Use %f to print a float. dcc detects literal formats automatically:
float r = sqrtf(2.0f);
printf("%f\n", r);
The -ffloatio option forces %f support on every printf-family call; it is
not required for a literal format and does not add floating-point scanf input.
Float output is supported by printf, sprintf, fprintf, their v... forms,
snprintf, and vsnprintf. See
Console and file I/O for the full formatted
I/O subset.
Accuracy¶
The transcendental routines (expf/logf/powf, the trig and hyperbolic
families) are single-precision polynomial and series approximations: expect
roughly 5-6 significant digits on ordinary ranges, not full float round-trip
accuracy. The range-reduction in sinf/cosf/tanf uses fmodf, so accuracy
gradually degrades for very large arguments.
Precision and mixed-type gotchas¶
floatcarries about 7 decimal digits (a 24-bit significand). Integers up to 2^24 (16,777,216) are exact; beyond that only some integers are representable.(long)(float)16777217Lis16777216, not16777217. The same rounding applies in constant expressions,caselabels, and array bounds.- Comparing a wide integer against a
floathappens infloat. The integer side converts first, so16777216L < (float)16777217Lis false (the cast rounded down to16777216.0f). Compare as integers when you need full 32-bit precision. - Any
floatarm makes a?:afloatexpression.cond ? 2 : 3.5fyields afloat, not anint; cast the result if you need an integer. - A
floatis "true" when its magnitude is nonzero.if (f),f ? a : b,!f,f && g, andwhile (f)test against zero, and both+0.0fand-0.0fcount as false.