Prev: Shell Sort
Next: matrix package with Ada
From: Adam Beneschan on 9 Jul 2010 15:06 I must be suffering from an embarrassing mental block, because I'm sure there's a simple solution, but I can't see what it is. I have a value X of a fixed-point type, X >= 0.0, and I need to compute Floor(X) as an Integer. 'Truncation and 'Floor aren't defined for fixed-point types; the type conversion Integer(X) rounds; and Integer(X-0.5) fails if X=0.0. How do others do this? Or do I have to resort to an IF statement (or conditional expression in Ada 2012) to handle the different cases? -- Adam
From: Simon Wright on 9 Jul 2010 16:34 Adam Beneschan <adam(a)irvine.com> writes: > I must be suffering from an embarrassing mental block, because I'm > sure there's a simple solution, but I can't see what it is. > > I have a value X of a fixed-point type, X >= 0.0, and I need to > compute Floor(X) as an Integer. 'Truncation and 'Floor aren't defined > for fixed-point types; the type conversion Integer(X) rounds; and > Integer(X-0.5) fails if X=0.0. > > How do others do this? Or do I have to resort to an IF statement (or > conditional expression in Ada 2012) to handle the different cases? Looks as though Integer(X+0.5)-1 might do the trick ..
From: Gene on 9 Jul 2010 16:39 On Jul 9, 3:06 pm, Adam Beneschan <a...(a)irvine.com> wrote: > I must be suffering from an embarrassing mental block, because I'm > sure there's a simple solution, but I can't see what it is. > > I have a value X of a fixed-point type, X >= 0.0, and I need to > compute Floor(X) as an Integer. 'Truncation and 'Floor aren't defined > for fixed-point types; the type conversion Integer(X) rounds; and > Integer(X-0.5) fails if X=0.0. > > How do others do this? Or do I have to resort to an IF statement (or > conditional expression in Ada 2012) to handle the different cases? > > -- Adam There is a prior discussion of this question: http://coding.derkeiler.com/Archive/Ada/comp.lang.ada/2003-10/0729.html The problem is that fixed point types don't have to include all the integers. An ugly approach is to convert to e.g. a long float, take the floor, and convert back. No doubt others will have something more elegant.
From: Jeffrey R. Carter on 9 Jul 2010 17:20 On 07/09/2010 01:39 PM, Gene wrote: > > An ugly approach is to convert to e.g. a long float, take the floor, > and convert back. No doubt others will have something more elegant. That's the approach I use, though, in the interest of portability, I declare my own floating-point type for the purpose: function Floor (Value : in Fixed) return Integer is type Big is digits System.Max_Digits; begin -- Floor return Integer (Big'Floor (Big (Value) ) ); end Floor; -- Jeff Carter "It's symbolic of his struggle against reality." Monty Python's Life of Brian 78
From: Adam Beneschan on 9 Jul 2010 17:52
On Jul 9, 1:39 pm, Gene <gene.ress...(a)gmail.com> wrote: > On Jul 9, 3:06 pm, Adam Beneschan <a...(a)irvine.com> wrote: > > > I must be suffering from an embarrassing mental block, because I'm > > sure there's a simple solution, but I can't see what it is. > > > I have a value X of a fixed-point type, X >= 0.0, and I need to > > compute Floor(X) as an Integer. 'Truncation and 'Floor aren't defined > > for fixed-point types; the type conversion Integer(X) rounds; and > > Integer(X-0.5) fails if X=0.0. > > > How do others do this? Or do I have to resort to an IF statement (or > > conditional expression in Ada 2012) to handle the different cases? > > > -- Adam > > There is a prior discussion of this question: > > http://coding.derkeiler.com/Archive/Ada/comp.lang.ada/2003-10/0729.html Thanks for the link. I was aware of AI95-60 but I hadn't been aware that the problem had been brought up again. > The problem is that fixed point types don't have to include all the > integers. Ah, I see. This is a problem because 'Truncation and 'Floor are defined to return the same fixed-point type. It seems to me that the language could use a way to do the truncation (or floor) and return an integer, without having to worry about an intermediate result of the same fixed-point type (which might not be a possible value of the type). I think someone mentioned that in the thread, but mentioned that it would probably have to be generic. > An ugly approach is to convert to e.g. a long float, take the floor, > and convert back. No doubt others will have something more elegant. That will probably work for my purpose; but in general, it's easy to define a fixed-point number with a 'Small of 2**(-N) that has more bits to the right of the binary point than are available in the mantissa part of the floating-point. If that's the case, this approach will fail on certain values (probably M - (K * T'Small) for integer M and suitably small integer K). Since this situation lends itself to really efficient code (basically just a bit shift), it's kind of a shame that the language doesn't give you a good way to do this. -- Adam |