Prev: Shell Sort
Next: matrix package with Ada
From: Shark8 on 9 Jul 2010 18:58 On Jul 9, 1: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 I'd think that 1-Integer(X+0.5) would work... wouldn't it?
From: Adam Beneschan on 9 Jul 2010 19:21 On Jul 9, 1:34 pm, Simon Wright <si...(a)pushface.org> wrote: > Adam Beneschan <a...(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 .. Yes, it looks like it, as long as X >= 0.0 and 0.5 is a model number of the fixed-point type (I think I'm using the right term). Those conditions do hold for the code I need it for. It isn't useful for negative numbers---it yields -2 if X=-1.0, which is not useful whether you want a truncation or a floor operation---but I did stipulate nonnegative X in my original question. -- Adam
From: Gene on 9 Jul 2010 23:13 On Jul 9, 7:21 pm, Adam Beneschan <a...(a)irvine.com> wrote: > On Jul 9, 1:34 pm, Simon Wright <si...(a)pushface.org> wrote: > > > Adam Beneschan <a...(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 .. > > Yes, it looks like it, as long as X >= 0.0 and 0.5 is a model number > of the fixed-point type (I think I'm using the right term). Those > conditions do hold for the code I need it for. It isn't useful for > negative numbers---it yields -2 if X=-1.0, which is not useful whether > you want a truncation or a floor operation---but I did stipulate > nonnegative X in my original question. > > -- Adam Shouldn't there be a way to convert a fixed point type to a corresponding modular or integer type with one integer value per floating point value, use rem to compute a floor, and convert back?
From: Simon Wright on 10 Jul 2010 04:12 Adam Beneschan <adam(a)irvine.com> writes: > On Jul 9, 1:34 pm, Simon Wright <si...(a)pushface.org> wrote: >> Adam Beneschan <a...(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 .. > > Yes, it looks like it, as long as X >= 0.0 and 0.5 is a model number > of the fixed-point type (I think I'm using the right term). Those > conditions do hold for the code I need it for. It isn't useful for > negative numbers---it yields -2 if X=-1.0, which is not useful whether > you want a truncation or a floor operation---but I did stipulate > nonnegative X in my original question. I hadn't considered the model number aspect, but nonnegative X is indeed necessary for this solution!
From: Gene on 11 Jul 2010 15:43
On Jul 9, 11:13 pm, Gene <gene.ress...(a)gmail.com> wrote: > On Jul 9, 7:21 pm, Adam Beneschan <a...(a)irvine.com> wrote: > > > > > > > On Jul 9, 1:34 pm, Simon Wright <si...(a)pushface.org> wrote: > > > > Adam Beneschan <a...(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 .. > > > Yes, it looks like it, as long as X >= 0.0 and 0.5 is a model number > > of the fixed-point type (I think I'm using the right term). Those > > conditions do hold for the code I need it for. It isn't useful for > > negative numbers---it yields -2 if X=-1.0, which is not useful whether > > you want a truncation or a floor operation---but I did stipulate > > nonnegative X in my original question. > > > -- Adam > > Shouldn't there be a way to convert a fixed point type to a > corresponding modular or integer type with one integer value per > floating point value, use rem to compute a floor, and convert back?- Hide quoted text - I'll try to answer my own question. Here is an attempt that works for a variety of fixed point types. I'm no expert on fixed point. Perhaps I've embedded some non-portable assumptions. With optimizations turned up and range checks off, the Floor function inlines as the 3 (x86) instructions you'd expect (subtract, "and" with mask, add) using GPL 2007. with Ada.Text_IO; use Ada.Text_IO; procedure FPF is type FP is delta 0.125 range -10.0 .. 50.0; function Floor(X : FP) return FP is Delta_Inv : constant := 1.0 / FP'Delta; type Bits is mod 2 ** 32; type FP_Bits is delta 1.0 range 0.0 .. (FP'Last - FP'First) * Delta_Inv; Ordinal : constant Bits := Bits((X - FP'First) * Delta_Inv) and not(Bits(Delta_Inv) - 1); begin return FP'Base(FP_Bits(Ordinal) * FP'Delta) + FP'First; end; X : FP := FP'First; begin loop Put_Line(FP'Image(X) & " -> " & FP'Image(Floor(X))); exit when X = FP'Last; X := X + FP'Delta; end loop; end; |