Mail Archives: djgpp/1997/11/03/03:29:32
On 2 Nov 1997, Mr Kevin Yeung wrote:
> assert(sprintf(buf, "%E|%.2f|%Lg", 1.1e20, -3.346, .02L) == 23);
> assert(strcmp(buf, "1.100000E+20|-3.35|0.02") == 0);
> assert(sscanf(buf, "%e|%lg|%Lf", &fl, &db, &ld) == 3);
> assert(fabs(fl - 1.1e20) / 1.1e20 < 4 * FLT_EPSILON);
> assert(fabs(db + 3.35) / 3.35 < 4 * DBL_EPSILON);
> assert(fabs(ld - 0.02) / 0.02 < 4 * LDBL_EPSILON);
> return(0);
> }
>
> It seems to be the problem of the string functions rather than that of the
> math functions.
You need to be more careful with your constants. Replace this line:
> assert(fabs(ld - 0.02) / 0.02 < 4 * LDBL_EPSILON);
with this:
> assert(fabs(ld - 0.02L) / 0.02 < 4 * LDBL_EPSILON);
(note the `L' after 0.02), and it will work as expected. When you use
0.02, the code uses double constant 0.02, which loses accuracy. As a
matter of principle, you should always use the same types when dealing
with floating-point code. Don't mix floats with doubles and doubles
with long doubles unless you both absolutely have to and know what you
are doing.
> But the maths functions don't trap EDOM errors is for
> sure.
Please post your code. I don't understand what does ``don't trap EDOM
errors'' mean.
In general, you need to link with -lm to get more compatible math
library, and if you want your program to set errno rather than crash
in certain cases (like sqrt(-1)), you need either to use `_control87'
library function to set certain bits of the x87 processor so that it
doesn't generate exceptions, or install a handler for signal SIGFPE.
- Raw text -