From: Shark8 on
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
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
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
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
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;
First  |  Prev  |  Next  |  Last
Pages: 1 2 3
Prev: Shell Sort
Next: matrix package with Ada