Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 04, 2003 cos bug | ||||
---|---|---|---|---|
| ||||
The following code return wrong result: #include <math.h> #include <stdio.h> int main() { float vf = 7.7915e19; double vd = 7.7915e19; long double vl = 7.7915e19; printf("cosf(%lg) = %lg\n", vf, cosf(vf)); printf("cos(%lg) = %lg\n", vd, cos(vd)); printf("cosl(%Lg) = %Lg", vl, cosl(vl)); return 0; } The output is: cosf(7.7915e+19) = 7.7915e+19 cos(7.7915e+19) = 7.7915e+19 cosl(7.7915e+19) = 7.7915e+19 The used compiler is Digital Mars Compiler v8.34. Regards, Steve |
June 05, 2003 Re: cos bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Hall | Steve Hall schrieb...
> include <math.h>
> #include <stdio.h>
>
> int main()
> {
> float vf = 7.7915e19;
> double vd = 7.7915e19;
> long double vl = 7.7915e19;
>
> printf("cosf(%lg) = %lg\n", vf, cosf(vf));
> printf("cos(%lg) = %lg\n", vd, cos(vd));
> printf("cosl(%Lg) = %Lg", vl, cosl(vl));
>
> return 0;
> }
>
> The output is:
> cosf(7.7915e+19) = 7.7915e+19
> cos(7.7915e+19) = 7.7915e+19
> cosl(7.7915e+19) = 7.7915e+19
>
> The used compiler is Digital Mars Compiler v8.34.
1. Why use such a huge number as argument to cos?
2. My old 486 Processor handbook tells me that the argument range is
abs(arg) < 2^63
2^63 = 9.2233e+18
I would assume this is also valid for the pentiom family?
So your argument is already out of range for the numeric coprozessor. When the coprocessor exception is ignored (as is with DM) then the argument on FPU stack isn't changed and you get back the argument unmodified.
- Heinz
|
June 05, 2003 Re: cos bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Heinz Saathoff | Heinz, thank you for your reply. dmc v3.34 is a C99 conformed compiler with IEC 60559 support according to macros __STDC_VERSION__(199901) and __STDC_IEC_559__. Types float and double are respectively single and double precision types from IEC 60559(Binary floating-point arithmetic for microprocessor systems, second edition). The floating-point standard is independent of the hardware. According to C99 the maximum representable number for type float is FLT_MAX = 3.40282347E+38, for type double is DBL_MAX = 1.7976931348623157E+308. Type double is subset of type long double, which is compiler dependent(for dmc v3.34 long double contain 80 bits). The same code compiled with gcc v3.2.3 (mingw special 20030504-1) return reasonable results for functions cos and cosf(the recent version of MinGW gcc doesn't support properly displaying of long double type thru printf function). The software that I develop depend on precision C99 floating-point arithmetic. Regards, Steve "Heinz Saathoff" <hsaat@bre.ipnet.de> wrote in message news:MPG.194952a884bb81f79896bc@news.digitalmars.com... > Steve Hall schrieb... > > include <math.h> > > #include <stdio.h> > > > > int main() > > { > > float vf = 7.7915e19; > > double vd = 7.7915e19; > > long double vl = 7.7915e19; > > > > printf("cosf(%lg) = %lg\n", vf, cosf(vf)); > > printf("cos(%lg) = %lg\n", vd, cos(vd)); > > printf("cosl(%Lg) = %Lg", vl, cosl(vl)); > > > > return 0; > > } > > > > The output is: > > cosf(7.7915e+19) = 7.7915e+19 > > cos(7.7915e+19) = 7.7915e+19 > > cosl(7.7915e+19) = 7.7915e+19 > > > > The used compiler is Digital Mars Compiler v8.34. > > 1. Why use such a huge number as argument to cos? > 2. My old 486 Processor handbook tells me that the argument range is > abs(arg) < 2^63 > 2^63 = 9.2233e+18 > I would assume this is also valid for the pentiom family? > > So your argument is already out of range for the numeric coprozessor. When the coprocessor exception is ignored (as is with DM) then the argument on FPU stack isn't changed and you get back the argument unmodified. > > - Heinz |
June 05, 2003 Re: cos bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Hall | In article <bbnl8t$2g9$1@digitaldaemon.com>, Steve Hall says... >The same code compiled with gcc v3.2.3 (mingw special 20030504-1) return reasonable results for functions cos and cosf(the recent version of MinGW gcc doesn't support properly displaying of long double type thru printf function). gcc may return a "reasonable"-looking result for cos and cosf, but that result is totally meaningless. The FPU is rejecting your calculation for good reason. If you start with, float vf = 7.7915e19; and subtract a multiple of 2*pi (=m) such that 0 <= vf - (m*2*pi) < 2*pi, all you are really left with is just random rounding error garbage. If you try to calculate (vf) - (vf - 1); do you really get 1? Maybe with 80 bits of precision; otherwise I don't think so. >The software that I develop depend on precision C99 floating-point arithmetic. If you really need to know the cosine of such a large number, I would suggest you use an arbitrary precision math package. Or else consider writing your own cos function that just returns zero if the argument is too large. But I don't know if it is good to slow down everyone else just for people with weird requirements performing meaningless cosine calculations. >Regards, >Steve Keith Fuller keithfx@h.tmail.com |
June 05, 2003 Re: cos bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Keith Fuller | >But I don't know if it is good to slow down everyone else just for people with weird requirements performing meaningless cosine calculations. Thanks for your answer. You are right that cos of big values return "just random rounding error garbage". Any value between [-1; 1] is acceptable for cos function with such argument. But value outside of this region is mathematicaly unacceptable. >If you really need to know the cosine of such a large number, I would suggest you use an arbitrary precision math package. Or else consider writing your own cos function that just returns zero if the argument is too large. In fact the compiler is mathematical based language translator. It must mathematical accurately to translate every piece of the code in precise machine readable form. If it fail, the compiled code will produce "just random rounding error garbage". What you think Walter about this (thanks for the correction of powl bug)? Do you accept to close your eyes in front of outstanding mathematical inaccuracy of your compiler? Do you accept to sell mathematical inaccurate compiler and prefer everyone of your clients to know that you haven't interest to correct such a poblems? Can I develop mathematical/logicaly stable software if the used compiler contain mathematical bugs? From your point of view all you need to do is just to ignore this post, because I'm the only one who want mathematical stable compiler. Thank you for your patience Walter, Steve Hall |
June 05, 2003 Re: cos bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Hall | "Steve Hall" <sthall@lorrexinc.com> wrote in message news:bboebu$ptk$1@digitaldaemon.com... > What you think Walter about this (thanks for the correction of powl bug)? > Do you accept to close your eyes in front of outstanding mathematical > inaccuracy of your compiler? Do you accept to sell mathematical inaccurate > compiler and prefer everyone of your clients to know that you haven't > interest to correct such a poblems? > Can I develop mathematical/logicaly stable software if the used compiler > contain mathematical bugs? > From your point of view all you need to do is just to ignore this post, > because I'm the only one who want mathematical stable compiler. > Thank you for your patience Walter, > Steve Hall The fundamental problem is DMC++ gets killed in benchmark comparisons unless cos() is recognized by the compiler and replaced with the single FCOS instruction. So, it is depending on the FPU to get it right. The FPU sets C2 if it is out of range, which you can test with the JP instruction. Alternatively, you can: #include <math.h> #undef cos which will disable the insertion of the fcos instruction, and will instead call the library cos() function. The library routine will test C2 and attempt argument reduction. It'll be significantly slower, though. To sum up, accurate and fast floating point are often at odds with each other. |
June 05, 2003 Re: cos bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Hall | >Can I develop mathematical/logicaly stable software if the used compiler contain mathematical bugs? If this were a meaningful calculation, I would agree with you. If this were another programming language, I would probably agree with you. But this is C. There is no lower-level language available. People using C would rather have the maximum performance and smallest code instead of catering to goofy calculations. >Thank you for your patience Walter, >Steve Hall Keith Fuller keithfx.h@tmail.com |
June 06, 2003 Re: cos bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Thank you Walter. Would you tell me how I can use cosl and sinl library functions? Do you intend to implement tgmath.h or do you have plans to finish C99 support for the math functions? Steve "Walter" <walter@digitalmars.com> wrote in message news:bbohg1$sh1$1@digitaldaemon.com... > > "Steve Hall" <sthall@lorrexinc.com> wrote in message news:bboebu$ptk$1@digitaldaemon.com... > > What you think Walter about this (thanks for the correction of powl bug)? > > Do you accept to close your eyes in front of outstanding mathematical inaccuracy of your compiler? Do you accept to sell mathematical inaccurate > > compiler and prefer everyone of your clients to know that you haven't > > interest to correct such a poblems? > > Can I develop mathematical/logicaly stable software if the used compiler > > contain mathematical bugs? > > From your point of view all you need to do is just to ignore this post, > > because I'm the only one who want mathematical stable compiler. > > Thank you for your patience Walter, > > Steve Hall > > > The fundamental problem is DMC++ gets killed in benchmark comparisons unless > cos() is recognized by the compiler and replaced with the single FCOS instruction. So, it is depending on the FPU to get it right. The FPU sets C2 > if it is out of range, which you can test with the JP instruction. > > Alternatively, you can: > > #include <math.h> > #undef cos > > which will disable the insertion of the fcos instruction, and will instead call the library cos() function. The library routine will test C2 and attempt argument reduction. It'll be significantly slower, though. > > To sum up, accurate and fast floating point are often at odds with each other. > > |
June 06, 2003 Re: cos bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Hall | Steve Hall schrieb... > dmc v3.34 is a C99 conformed compiler with IEC 60559 support according to macros __STDC_VERSION__(199901) and __STDC_IEC_559__. Types float and double are respectively single and double precision types from IEC 60559(Binary floating-point arithmetic for microprocessor systems, second edition). The floating-point standard is independent of the hardware. I don't have the C99 Standard here but would assume that the floating point specs rely on the IEEE spec, and that is the basic for FPU implementations. > According to C99 the maximum representable number for type float is FLT_MAX = 3.40282347E+38, for type double is DBL_MAX = 1.7976931348623157E+308. Type double is subset of type long double, which is compiler dependent(for dmc v3.34 long double contain 80 bits). So far DMC doesn't have a problem. It would be interesting to see what the C99 standard tells about argument ranges. Is it required for sin/cos to provide a reasonable (not correct, only range [-1,1]) result for all float/double arguments? What about tan, when the huge argument reduces to PI/2? > The same code compiled with gcc v3.2.3 (mingw special 20030504-1) return reasonable results for functions cos and cosf(the recent version of MinGW gcc doesn't support properly displaying of long double type thru printf function). I don't have access to mingw. Maybe the compiler evaluates the FPU flags to detect the fault and corrects ist? To Walter: is this where the difference between -f and -ff is? As I understand the -ff (fast floating point) option doesn't check for special cases (nan, overflows). - Heinz |
June 06, 2003 Re: cos bug | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Hall | "Steve Hall" <sthall@lorrexinc.com> wrote in message news:bbpms5$1uae$1@digitaldaemon.com... > Would you tell me how I can use cosl and sinl library functions? At the moment, you can just use the inline FCOS and FSIN versions. > Do you intend to implement tgmath.h That turns out to be a **** to implement. > or do you have plans to finish C99 > support for the math functions? Yes. |
Copyright © 1999-2021 by the D Language Foundation