* I think - it's a bug... @ 2002-03-10 8:24 Anatoly Chernyshev 2002-03-10 12:58 ` David C. Hoos, Sr. ` (3 more replies) 0 siblings, 4 replies; 12+ messages in thread From: Anatoly Chernyshev @ 2002-03-10 8:24 UTC (permalink / raw) Hello everybody! Look at this piece of code: ------------------------------------------------------------------------------------------------- WITH ada.text_io,ada.numerics.elementary_functions; USE ada.text_io, ada.numerics.elementary_functions; PROCEDURE el_stat_fun IS b : float := 7.5; a:float:=4.0; rr, z : float; r : float := 4.0; dz : float := 0.3; BEGIN FOR k IN 0..integer(b/dz) LOOP z:=float(k)*dz; put_line (float'image(1.0-(z/b))); rr:=-a*sqrt((1.0-(z/b)**2))+a+r; END LOOP; END el_stat_fun; ---------------------------------------------------------------------------------------------------- When compiled using GNAT 3.14 (WinNT sp 6) it raises ADA.NUMERICS.ARGUMENT_ERROR in sqrt function when k goes to 25 because the argument for sqrt becomes negative (like -X.XXXXXE-07 ... And this is a headache No 1). However, if one comments out the put_line string - everything works fine. I don't know whether this is a bug or feature, but any kind of help for how to avoid the situation when 1.0-1.0/1.0 yields something different from 0.0 will be greatly appreciated. Thanks in advance, Anatoly. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-10 8:24 I think - it's a bug Anatoly Chernyshev @ 2002-03-10 12:58 ` David C. Hoos, Sr. 2002-03-11 5:33 ` Anatoly Chernyshev ` (2 more replies) 2002-03-11 5:32 ` Jeffrey Carter ` (2 subsequent siblings) 3 siblings, 3 replies; 12+ messages in thread From: David C. Hoos, Sr. @ 2002-03-10 12:58 UTC (permalink / raw) This is not a bug. The problem comes about by not being aware of the nature of floating point representation in computers. In your example, the value of dz (0.3) is not exactly representable in binary -- it is an infinitely repeating binary fraction. Hence, all values of z that you compute are not exactly representable. Thus, if the value of dz was rounded upward to the next lsb when converting from decimal to binary, all values of z will be slightly larger than their true value. The only solution is to test the values of which you are about to take the square root, and if the absolute value is less than some very small threshold, set the value to 0.0. Alternatively, if you are sure (given the nature of the problem you are solving) that z can never be greater than b, you could replace (z/b) by Float'Min (1.0, z/b). Additionally, you might want to consider the following statement from the GNAT User's Guide: In particular, if the Ada code will do any floating-point operations, then the FPU must be setup in an appropriate manner. For the case of the x86, for example, full precision mode is required. The procedure GNAT.Float_Control.Reset may be used to ensure that the FPU is in the right state. Finally you can obtain greater precision by using Long_Float or Long_Long_Float instead of Float. ----- Original Message ----- From: "Anatoly Chernyshev" <rhezusfactor@yahoo.com> Newsgroups: comp.lang.ada To: <comp.lang.ada@ada.eu.org> Sent: March 10, 2002 2:24 AM Subject: I think - it's a bug... > Hello everybody! > > Look at this piece of code: > > ---------------------------------------------------------------------------- --------------------- > > WITH ada.text_io,ada.numerics.elementary_functions; > USE ada.text_io, ada.numerics.elementary_functions; > PROCEDURE el_stat_fun IS > b : float := 7.5; > a:float:=4.0; > rr, z : float; > r : float := 4.0; > dz : float := 0.3; > BEGIN > FOR k IN 0..integer(b/dz) LOOP > z:=float(k)*dz; > put_line (float'image(1.0-(z/b))); > rr:=-a*sqrt((1.0-(z/b)**2))+a+r; > END LOOP; > END el_stat_fun; > ---------------------------------------------------------------------------- ------------------------ > > > > > When compiled using GNAT 3.14 (WinNT sp 6) it raises > ADA.NUMERICS.ARGUMENT_ERROR in sqrt function when k goes to 25 because > the argument for sqrt becomes > negative (like -X.XXXXXE-07 ... And this is a headache No 1). > However, if one comments out the put_line string - everything works > fine. > > I don't know whether this is a bug or feature, but any kind of help for > how to avoid the situation when 1.0-1.0/1.0 yields something different > from 0.0 will be greatly appreciated. > > Thanks in advance, > > Anatoly. > > > > > > > _______________________________________________ > comp.lang.ada mailing list > comp.lang.ada@ada.eu.org > http://ada.eu.org/mailman/listinfo/comp.lang.ada > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-10 12:58 ` David C. Hoos, Sr. @ 2002-03-11 5:33 ` Anatoly Chernyshev 2002-03-11 13:43 ` David C. Hoos 2002-03-11 16:13 ` Stephen Leake 2002-03-11 5:39 ` Jeffrey Carter 2002-03-11 14:53 ` Wes Groleau 2 siblings, 2 replies; 12+ messages in thread From: Anatoly Chernyshev @ 2002-03-11 5:33 UTC (permalink / raw) "David C. Hoos, Sr." wrote: > This is not a bug. The problem comes about by not being aware of > the nature of floating point representation in computers. > > In your example, the value of dz (0.3) is not exactly representable in > binary -- it is an infinitely repeating binary fraction. Hence, all values of > z that you compute are not exactly representable. > > Thus, if the value of dz was rounded upward to the next lsb when > converting from decimal to binary, all values of z will be slightly > larger than their true value. > That's true, but still, why inserting of "put_line (float'image(1.0-(z/b)));" influences the behaviour of the program so much. Beyound that, I've got similar things with z=0.1 and 0.25. They were solved though, by using different optomization levels (-O, -O2...). > > The only solution is to test the values of which you are about to take > the square root, and if the absolute value is less than some very small > threshold, set the value to 0.0. > > Alternatively, if you are sure (given the nature of the problem you > are solving) that z can never be greater than b, you could replace > (z/b) by Float'Min (1.0, z/b). > > Additionally, you might want to consider the following statement > from the GNAT User's Guide: > In particular, if the Ada code will do any floating-point operations, > then the FPU must be setup in an appropriate manner. For the case > of the x86, for example, full precision mode is required. The > procedure GNAT.Float_Control.Reset may be used to ensure that > the FPU is in the right state. > Finally you can obtain greater precision by using Long_Float or Long_Long_Float > instead of Float. Thanks a lot for those suggestions (but you are omitted what is coming from the GNAT UG). > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-11 5:33 ` Anatoly Chernyshev @ 2002-03-11 13:43 ` David C. Hoos 2002-03-11 16:13 ` Stephen Leake 1 sibling, 0 replies; 12+ messages in thread From: David C. Hoos @ 2002-03-11 13:43 UTC (permalink / raw) I think what happens when the put_line call is present is that the C runtime library is called, which on NT can result in the FPU unit state being changed, hence the desirability (or need) to call GNAT.Float_Control.Reset, as suggested. The statement from the UG _was_ included, and is: In particular, if the Ada code will do any floating-point operations, then the FPU must be setup in an appropriate manner. For the case of the x86, for example, full precision mode is required. The procedure GNAT.Float_Control.Reset may be used to ensure that the FPU is in the right state. ----- Original Message ----- From: "Anatoly Chernyshev" <rhezusfactor@yahoo.com> Newsgroups: comp.lang.ada To: <comp.lang.ada@ada.eu.org> Sent: Sunday, March 10, 2002 11:33 PM Subject: Re: I think - it's a bug... > > > "David C. Hoos, Sr." wrote: > > > This is not a bug. The problem comes about by not being aware of > > the nature of floating point representation in computers. > > > > In your example, the value of dz (0.3) is not exactly representable in > > binary -- it is an infinitely repeating binary fraction. Hence, all values of > > z that you compute are not exactly representable. > > > > Thus, if the value of dz was rounded upward to the next lsb when > > converting from decimal to binary, all values of z will be slightly > > larger than their true value. > > > > That's true, but still, why inserting of "put_line (float'image(1.0-(z/b)));" > influences the behaviour of the program so much. > Beyound that, I've got similar things with z=0.1 and 0.25. They were solved > though, by using different optomization levels (-O, -O2...). > > > > > > The only solution is to test the values of which you are about to take > > the square root, and if the absolute value is less than some very small > > threshold, set the value to 0.0. > > > > Alternatively, if you are sure (given the nature of the problem you > > are solving) that z can never be greater than b, you could replace > > (z/b) by Float'Min (1.0, z/b). > > > > Additionally, you might want to consider the following statement > > from the GNAT User's Guide: > > In particular, if the Ada code will do any floating-point operations, > > then the FPU must be setup in an appropriate manner. For the case > > of the x86, for example, full precision mode is required. The > > procedure GNAT.Float_Control.Reset may be used to ensure that > > the FPU is in the right state. > > > Finally you can obtain greater precision by using Long_Float or Long_Long_Float > > instead of Float. > > Thanks a lot for those suggestions (but you are omitted what is coming from the > GNAT UG). > > > > > _______________________________________________ > comp.lang.ada mailing list > comp.lang.ada@ada.eu.org > http://ada.eu.org/mailman/listinfo/comp.lang.ada > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-11 5:33 ` Anatoly Chernyshev 2002-03-11 13:43 ` David C. Hoos @ 2002-03-11 16:13 ` Stephen Leake 1 sibling, 0 replies; 12+ messages in thread From: Stephen Leake @ 2002-03-11 16:13 UTC (permalink / raw) Anatoly Chernyshev <rhezusfactor@yahoo.com> writes: > That's true, but still, why inserting of "put_line (float'image(1.0-(z/b)));" > influences the behaviour of the program so much. > Beyound that, I've got similar things with z=0.1 and 0.25. They were solved > though, by using different optomization levels (-O, -O2...). Since that is the _only_ place you have Text_IO, if you leave out the "put_line", Text_IO is not linked in. Then you don't need the Microsoft runtime library. The Microsoft runtime library sets the FPU to the "wrong" mode. If you Use GNAT.Float_Control.Reset, the presence of "put_line" will no longer matter. -- -- Stephe ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-10 12:58 ` David C. Hoos, Sr. 2002-03-11 5:33 ` Anatoly Chernyshev @ 2002-03-11 5:39 ` Jeffrey Carter 2002-03-11 14:53 ` Wes Groleau 2 siblings, 0 replies; 12+ messages in thread From: Jeffrey Carter @ 2002-03-11 5:39 UTC (permalink / raw) "David C. Hoos, Sr." wrote: > > Additionally, you might want to consider the following statement > from the GNAT User's Guide: > In particular, if the Ada code will do any floating-point operations, > then the FPU must be setup in an appropriate manner. For the case > of the x86, for example, full precision mode is required. The > procedure GNAT.Float_Control.Reset may be used to ensure that > the FPU is in the right state. Note that this is in the section "Binding with Non-Ada Main Programs", which clearly doesn't apply in this case. -- Jeff Carter "English bed-wetting types." Monty Python & the Holy Grail ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-10 12:58 ` David C. Hoos, Sr. 2002-03-11 5:33 ` Anatoly Chernyshev 2002-03-11 5:39 ` Jeffrey Carter @ 2002-03-11 14:53 ` Wes Groleau 2002-03-11 15:15 ` David C. Hoos 2 siblings, 1 reply; 12+ messages in thread From: Wes Groleau @ 2002-03-11 14:53 UTC (permalink / raw) > This is not a bug. The problem comes about by not being aware of > the nature of floating point representation in computers. Unless I misunderstood the original post, there IS a bug. If commenting out this > > put_line (float'image(1.0-(z/b))); causes this to stop raising an exception > > rr:=-a*sqrt((1.0-(z/b)**2))+a+r; then I think there must be a bug in the optimizer. But it should be sent to report@gnat.com and not to comp.lang.ada -- Wes Groleau http://freepages.rootsweb.com/~wgroleau ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-11 14:53 ` Wes Groleau @ 2002-03-11 15:15 ` David C. Hoos 0 siblings, 0 replies; 12+ messages in thread From: David C. Hoos @ 2002-03-11 15:15 UTC (permalink / raw) There are two problems, viz. 1. When z is essentially equal to b but (say) 1 lsb greater, then z/b is greater than 1.0, causing a negative argument to sqrt. 2. The problem with commenting out the put_line statement I believe to be a documented case where the NT C runtime can leave the FPU in a bad state. ----- Original Message ----- From: "Wes Groleau" <wesgroleau@despammed.com> Newsgroups: comp.lang.ada To: <comp.lang.ada@ada.eu.org> Sent: Monday, March 11, 2002 8:53 AM Subject: Re: I think - it's a bug... > > > This is not a bug. The problem comes about by not being aware of > > the nature of floating point representation in computers. > > Unless I misunderstood the original post, there IS a bug. > > If commenting out this > > > > put_line (float'image(1.0-(z/b))); > > causes this to stop raising an exception > > > > rr:=-a*sqrt((1.0-(z/b)**2))+a+r; > > then I think there must be a bug in the optimizer. > > But it should be sent to report@gnat.com and not to comp.lang.ada > > -- > Wes Groleau > http://freepages.rootsweb.com/~wgroleau > _______________________________________________ > comp.lang.ada mailing list > comp.lang.ada@ada.eu.org > http://ada.eu.org/mailman/listinfo/comp.lang.ada > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-10 8:24 I think - it's a bug Anatoly Chernyshev 2002-03-10 12:58 ` David C. Hoos, Sr. @ 2002-03-11 5:32 ` Jeffrey Carter 2002-03-11 5:46 ` Anatoly Chernyshev 2002-03-11 8:19 ` Phil Thornley 2002-03-11 19:48 ` Anatoly Chernyshev 3 siblings, 1 reply; 12+ messages in thread From: Jeffrey Carter @ 2002-03-11 5:32 UTC (permalink / raw) Anatoly Chernyshev wrote: > > WITH ada.text_io,ada.numerics.elementary_functions; > USE ada.text_io, ada.numerics.elementary_functions; > PROCEDURE el_stat_fun IS > b : float := 7.5; > a:float:=4.0; > rr, z : float; > r : float := 4.0; > dz : float := 0.3; B, A, R, and Dz are constants. Why not make them named numbers? > BEGIN > FOR k IN 0..integer(b/dz) LOOP > z:=float(k)*dz; > put_line (float'image(1.0-(z/b))); > rr:=-a*sqrt((1.0-(z/b)**2))+a+r; The parentheses here look funny. Did you perhaps mean rr:=-a*sqrt((1.0-(z/b))**2)+a+r; ? > END LOOP; > END el_stat_fun; -- Jeff Carter "English bed-wetting types." Monty Python & the Holy Grail ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-11 5:32 ` Jeffrey Carter @ 2002-03-11 5:46 ` Anatoly Chernyshev 0 siblings, 0 replies; 12+ messages in thread From: Anatoly Chernyshev @ 2002-03-11 5:46 UTC (permalink / raw) Jeffrey Carter wrote: > Anatoly Chernyshev wrote: > > > > WITH ada.text_io,ada.numerics.elementary_functions; > > USE ada.text_io, ada.numerics.elementary_functions; > > PROCEDURE el_stat_fun IS > > b : float := 7.5; > > a:float:=4.0; > > rr, z : float; > > r : float := 4.0; > > dz : float := 0.3; > > B, A, R, and Dz are constants. Why not make them named numbers? This was cut from the much bigger program, actually there they are not constants. > > The parentheses here look funny. Did you perhaps mean > > rr:=-a*sqrt((1.0-(z/b))**2)+a+r; This is just a mistyping - I meant what I meant. Anyway, after removing of extra brackets the problem still persists. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-10 8:24 I think - it's a bug Anatoly Chernyshev 2002-03-10 12:58 ` David C. Hoos, Sr. 2002-03-11 5:32 ` Jeffrey Carter @ 2002-03-11 8:19 ` Phil Thornley 2002-03-11 19:48 ` Anatoly Chernyshev 3 siblings, 0 replies; 12+ messages in thread From: Phil Thornley @ 2002-03-11 8:19 UTC (permalink / raw) "Anatoly Chernyshev" <rhezusfactor@yahoo.com> wrote in message news:3C8B184D.49214059@yahoo.com... > Hello everybody! > > Look at this piece of code: > > ---------------------------------------------------------------------- --------------------------- > > WITH ada.text_io,ada.numerics.elementary_functions; > USE ada.text_io, ada.numerics.elementary_functions; > PROCEDURE el_stat_fun IS > b : float := 7.5; > a:float:=4.0; > rr, z : float; > r : float := 4.0; > dz : float := 0.3; > BEGIN > FOR k IN 0..integer(b/dz) LOOP > z:=float(k)*dz; > put_line (float'image(1.0-(z/b))); > rr:=-a*sqrt((1.0-(z/b)**2))+a+r; > END LOOP; > END el_stat_fun; > ---------------------------------------------------------------------- ------------------------------ > > > > > When compiled using GNAT 3.14 (WinNT sp 6) it raises > ADA.NUMERICS.ARGUMENT_ERROR in sqrt function when k goes to 25 because > the argument for sqrt becomes > negative (like -X.XXXXXE-07 ... And this is a headache No 1). > However, if one comments out the put_line string - everything works > fine. > You need to look at the generated code. All the variables are local to the procedure, so if you comment out the Put_Line then the compiler might be generating no code at all for the procedure. Alternatively try changing it so that the variable rr is external to the procedure (and make it volatile as well). Cheers, Phil -- Phil Thornley Programmes, Engineering Warton ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: I think - it's a bug... 2002-03-10 8:24 I think - it's a bug Anatoly Chernyshev ` (2 preceding siblings ...) 2002-03-11 8:19 ` Phil Thornley @ 2002-03-11 19:48 ` Anatoly Chernyshev 3 siblings, 0 replies; 12+ messages in thread From: Anatoly Chernyshev @ 2002-03-11 19:48 UTC (permalink / raw) Thanks to everyone who tried to answer this post. Eventually, I've found a solution that always put me on the safe side: replace FOR k IN 0..integer(b/dz) LOOP with FOR K IN 0..Integer(Float'Truncation(B/Dz)) LOOP Anatoly Chernyshev wrote: > Look at this piece of code: > > ------------------------------------------------------------------------------------------------- > > WITH ada.text_io,ada.numerics.elementary_functions; > USE ada.text_io, ada.numerics.elementary_functions; > PROCEDURE el_stat_fun IS > b : float := 7.5; > a:float:=4.0; > rr, z : float; > r : float := 4.0; > dz : float := 0.3; > BEGIN > FOR k IN 0..integer(b/dz) LOOP > z:=float(k)*dz; > put_line (float'image(1.0-(z/b))); > rr:=-a*sqrt((1.0-(z/b)**2))+a+r; > END LOOP; > END el_stat_fun; > ---------------------------------------------------------------------------------------------------- > > When compiled using GNAT 3.14 (WinNT sp 6) it raises > ADA.NUMERICS.ARGUMENT_ERROR in sqrt function when k goes to 25 because > the argument for sqrt becomes > negative (like -X.XXXXXE-07 ... And this is a headache No 1). > However, if one comments out the put_line string - everything works > fine. > > I don't know whether this is a bug or feature, but any kind of help for > how to avoid the situation when 1.0-1.0/1.0 yields something different > from 0.0 will be greatly appreciated. > > Thanks in advance, > > Anatoly. ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2002-03-11 19:48 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-03-10 8:24 I think - it's a bug Anatoly Chernyshev 2002-03-10 12:58 ` David C. Hoos, Sr. 2002-03-11 5:33 ` Anatoly Chernyshev 2002-03-11 13:43 ` David C. Hoos 2002-03-11 16:13 ` Stephen Leake 2002-03-11 5:39 ` Jeffrey Carter 2002-03-11 14:53 ` Wes Groleau 2002-03-11 15:15 ` David C. Hoos 2002-03-11 5:32 ` Jeffrey Carter 2002-03-11 5:46 ` Anatoly Chernyshev 2002-03-11 8:19 ` Phil Thornley 2002-03-11 19:48 ` Anatoly Chernyshev
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox