Board index » delphi » Turbo Pascal and Reals and Integers

Turbo Pascal and Reals and Integers

Quote
Jonas Sandman wrote:

> I use Turbo Pascal 7.0 for DOS in school and I wonder if you can convert a
> "real" to an "integer" somehow? It is not needed in Delphi as far as I know
> but TP seems to be less user friendly :(

> If you know how, mail me!

> Jonas Sandman
> jonas.sand...@mail.bip.net

i : integer;
r : real;

i := trunc(r);
    or
i := round(r);

I think these should work for you.

 

Re:Turbo Pascal and Reals and Integers


I use Turbo Pascal 7.0 for DOS in school and I wonder if you can convert a
"real" to an "integer" somehow? It is not needed in Delphi as far as I know
but TP seems to be less user friendly :(

If you know how, mail me!

Jonas Sandman
jonas.sand...@mail.bip.net

Re:Turbo Pascal and Reals and Integers


Jonas Sandman <jonas.sand...@mail.bip.net> wrote in article
<01bcefa2$ff12e4e0$1ea8edc2@foo>...

Quote
> I use Turbo Pascal 7.0 for DOS in school and I wonder if you can convert
a
> "real" to an "integer" somehow? It is not needed in Delphi as far as I
know
> but TP seems to be less user friendly :(

> If you know how, mail me!

> Jonas Sandman
> jonas.sand...@mail.bip.net

Trunc will round the real down to the nearest integer. Round will round the
real to the nearest integer, up or down.

  Round(1.5)  = 2
  Round(-1.5) = -2
  Trunc(1.5)  = 1
  Trunc(-1.5) = -1

Frank

Re:Turbo Pascal and Reals and Integers


In article <01bcefa2$ff12e4e0$1ea8edc2@foo>,

Quote
Jonas Sandman <jonas.sand...@mail.bip.net> wrote:
>I use Turbo Pascal 7.0 for DOS in school and I wonder if you can convert a
>"real" to an "integer" somehow? It is not needed in Delphi as far as I know
>but TP seems to be less user friendly :(

You have a strange definition of user friendly. IMO warning on potential
errors is very user friendly. Assigning a real to an integer is can cause
loss of accuracy and even an error. Therefore it is good that the user
has to specify exactly how the value is modified (rounding or
truncating, round() or trunc()). On the other hand assigning integers to
reals have no problems. (OK, exception, if you assign longint into a
single you can loose accuracy as single has only 23 bits (+sign) for
mantissa. Real on the other hand has 39 bits so it can store any
longint accurately.)

Osmo

Re:Turbo Pascal and Reals and Integers


Quote
Frank Peelo wrote:

> Jonas Sandman <jonas.sand...@mail.bip.net> wrote in article
> <01bcefa2$ff12e4e0$1ea8edc2@foo>...
> > I use Turbo Pascal 7.0 for DOS in school and I wonder if you can convert
> a
> > "real" to an "integer" somehow? It is not needed in Delphi as far as I
> know
> > but TP seems to be less user friendly :(

whatever that means.

Quote
> Trunc will round the real down to the nearest integer. Round will round the
> real to the nearest integer, up or down.

>   Round(1.5)  = 2
>   Round(-1.5) = -2

This is only somewhat true.  ( boolean(17) :-) )

In the following code
var  r : real;
begin
  writeln (round(-1.5));
  writeln (round(-2.5));
  r := -1.5; writeln (round(r));
  r := -2.5; writeln (round(r));
  r := 1.5; writeln (round(r));
  r := 2.5; writeln (round(r));
end.

we get printed out
-2
-3
-2
-2  <= note this one.
2
2  <= note this one also.

This happens for single and double also.  I have read in this group that
this jitter was due to some accounting type definition of round.  I do
not know any more than that I don't like it.  Depending on your usage
this may matter.

My substitue function is
Function integ( value : single):integer;
  if (value>=0)
    then integ := trunc(value+0.5)
    else integ := trunc(value-0.49999999999999999);
end; { integ }

I chose -0.49999 kind-o-willynilly.  I have no real reason for that many
digits.  I imagine it should end in a 5 though.

Quote
> Frank

Ephram Cohen
Programmer
Auditory Lab UC Berkeley

Re:Turbo Pascal and Reals and Integers


In article <346CA276.AC611...@ear.berkeley.edu>,
Ephram Cohen  <eph...@ear.berkeley.edu> wrote:

Quote

>In the following code
>var  r : real;
>begin
>  writeln (round(-1.5));
>  writeln (round(-2.5));
>  r := -1.5; writeln (round(r));
>  r := -2.5; writeln (round(r));
>  r := 1.5; writeln (round(r));
>  r := 2.5; writeln (round(r));
>end.

>we get printed out
>-2
>-3
>-2
>-2  <= note this one.
>2
>2  <= note this one also.

I tried it and got:

-2
-3
-2
-3
2
3

Try running it with $N-.

Quote

>This happens for single and double also.  I have read in this group that
>this jitter was due to some accounting type definition of round.  I do
>not know any more than that I don't like it.  Depending on your usage
>this may matter.

It may be that the round is towards an even value.

Quote
>My substitue function is
>Function integ( value : single):integer;
>  if (value>=0)
>    then integ := trunc(value+0.5)
>    else integ := trunc(value-0.49999999999999999);
>end; { integ }

Why not

Function integ( value : single):integer;
begin
   integ:=(2*ord(s>0)-1)*trunc(abs(value)+0.5);
end;

Osmo

Re:Turbo Pascal and Reals and Integers


In article <346DF975.59436...@ear.berkeley.edu>,
Ephram Cohen  <eph...@ear.berkeley.edu> wrote:

Quote
>Osmo Ronkanen wrote:

...

>> I tried it and got:

>> -2
>> -3
>> -2
>> -3
>> 2
>> 3

>> Try running it with $N-.

>Whay would I possibly want to do this?  Floating point emulation in
>software has got to be significantly slower that using the hardware
>floating point.  Is this not true?  Are there some other benefits I do
>not know about?

My point was to show that the problem is not on Turbo Pascal floating
point routines. The fact that you used Reals implied that. Btw why on
earth would you use reals with coprocessor? On earlier processors that
could be slower than using $N-.

Also using reals with $N- has nothing whatsoever to do with any
emulation. Emulation is done with $N+,E+.

Quote

>> It may be that the round is towards an even value.

>Possibly.  What anoys me is that it does not do what is IMO
>mathematically expected.  What anoys me more is that there are different
>results with the software emulation v actual hardware.

You get exactly same results with emulation. I do not have a
coprocessor so emulation is the only way that I can do fp-operations
when I have $N+. I verified your results with emulation. Again
calculating floating point with software is not necessarily emulation.

Quote

>> Function integ( value : single):integer;
>> begin
>>    integ:=(2*ord(s>0)-1)*trunc(abs(value)+0.5);
>> end;

>Although I know this works and why it does it seems rather obfuscated to
>me.  Big benefit in yours is that there is no branching.  

IMO the big benefit is that one does not have to choose any ugly
0.4999999999. Also one can understand more easily why it works.

If you want to include a branch then sure you can do that:

Function integ( value : single):integer;
 begin
    if s<0 then integ:=-trunc(-value+0.5)
           else integ:=trunc(value+0.5);
 end;

My point was to get rid of the 0.49999999, not with the branch.

Quote
>I happen to like the readability of mine.  

I do not think the 0.499999999 makes it very readable.  Also there is
the fact that your code does not work with emulation. I got -1 when I
tried integ(-1.5). Now with emulation I really mean emulation.

Quote
>Anyone care to comment on the runtime for each?  I suppose I could
>benchmark them, but I was hoping for more of a little discussion on
>predictive branching and dual pipelines v a few multiplies and whatnots.

>> Osmo

>Ephram

Osmo

Re:Turbo Pascal and Reals and Integers


Quote
Osmo Ronkanen wrote:

> In article <346DF975.59436...@ear.berkeley.edu>,
> Ephram Cohen  <eph...@ear.berkeley.edu> wrote:
> >Osmo Ronkanen wrote:
[...]

> My point was to show that the problem is not on Turbo Pascal floating
> point routines. The fact that you used Reals implied that.

True enough but I did the test with single and double too.  Same results
as real.
[...]

Quote
> Also using reals with $N- has nothing whatsoever to do with any
> emulation. Emulation is done with $N+,E+.

I had to go look here and what I found is that there are three floating
point options

1) $N- "software runtime library" real type only
2) $N+$E+ 80x87 emulator. real, single... allowed
3) $N+$E- actually use 80x87

In my admitedly simple tests I found that option 2 and 3 behaved the
same so this can be reduced to "software runtime" v 80x87 ($N- v $N+).

[...]

Quote
> >there are different
> >results with the software emulation v actual hardware.

Ok, the differences are between software runtime and hardware not
emulation v hardware that I said here.

[...]

Quote
> IMO the big benefit is that one does not have to choose any ugly
> 0.4999999999. Also one can understand more easily why it works.

Point well taken.  

Quote
>  Also there is
> the fact that your code does not work with emulation. I got -1 when I
> tried integ(-1.5).

This is true.  I forgot to mention that my code always rounds "towards
the positive" for .5 values :-).  What is defined in the pascal doc's is
rounds "away from zero" for the .5 cases.  Since I was "fixing" round I
decided to do it "towards the positive".  It makes sense for the types
of things that I do at work.

The original point that I was trying to make was
{$N+}
var r : real;
begin
  r := 2.5;
  writeln (round(r):3,round(2.5):3);
end.
procuded 2 3
while
{$N-}
produced 3 3

I was mainly trying to make the original poster aware of this
discrepancy. so they could make a more informed choice as to what round
does v what they might want it to do.

Quote
> >> Osmo

> >Ephram

> Osmo

Ephram

Re:Turbo Pascal and Reals and Integers


On 13 Nov 1997 00:34:29 GMT, "Frank Peelo" <fpe...@indigo.ie> wrote:

Quote
>Trunc will round the real down to the nearest integer. Round will round the
>real to the nearest integer, up or down.

>  Round(1.5)  = 2
>  Round(-1.5) = -2

  Round(2.5)  = 3
  Round(-2.5) = -3

Quote
>  Trunc(1.5)  = 1
>  Trunc(-1.5) = -1

This topic needs some clarification.

If the fractional part is exactly 0.5, the behaviour depends on the
setting of the $N switch. With $N- (data type REAL), it is rounded
towards the longint with greater absolute value as you correctly
described. With $N+ (data types REAL,SINGLE,DOUBLE,EXTENDED) it is
rounded to the nearest even integer in case .5

{$N+}
const
  r25:real=2.5;
  e25:extended=2.5;
  r35:real=2.5;
  e35:extended=2.5;
begin
  writeln(round(r25)); { -> 2 };
  writeln(round(e25)); { -> 2 };
  writeln(round(r35)); { -> 4 };
  writeln(round(e35)); { -> 4 };
end;

This is one of the reasons why you should never use REAL and $N+.
Another reason is the terrible performance of REAL + $N+.

Look at this one.

{$N+}
const
  c25=2.5;
  e25:extended=2.5;
begin
  writeln(round(c25)); { -> 3  !!!!!!!!!!! };
  writeln(round(e25)); { -> 2 };
end;

This is a {*word*193} inconsistency (which I would call a bug) in all TP
versions which support FPU types. It was know to Borland but they
never corrected it.

The problem is that the round-instruction for c25 in the first
statement is evaluated at compile time (the program is executing
literally writeln(3)) and the second one is evaluated at run time. The
first one uses the rounding definition for REAL (the implementors
obviously didn't care to make constant's rounding at compile time
depend on the current state of $N), the second one uses the rounding
definition for FPU types.

This only a marginal problem, of course. Everybody who relies on a
special rounding definition using floating point data types is using
the wrong data type for his problem anyway, i.e. if the rounding
definition would be essential for the correctness of your program you
have to use an integral data type and round "by hand".

Regards
Horst

Re:Turbo Pascal and Reals and Integers


In article <346F41AB.22826...@ear.berkeley.edu>,
Ephram Cohen  <eph...@ear.berkeley.edu> wrote:

Quote
>Osmo Ronkanen wrote:

>> Also using reals with $N- has nothing whatsoever to do with any
>> emulation. Emulation is done with $N+,E+.

>I had to go look here and what I found is that there are three floating
>point options

>1) $N- "software runtime library" real type only
>2) $N+$E+ 80x87 emulator. real, single... allowed
>3) $N+$E- actually use 80x87

>In my admitedly simple tests I found that option 2 and 3 behaved the
>same so this can be reduced to "software runtime" v 80x87 ($N- v $N+).

If you have a coprocessor then 2 and 3 are naturally identical. The
emulation is only used when there is a no coprocessor. $N+,E+ is so that
one can produce programs that run fast on co-processor but also run on
computers without one. If you want to test the actual emulation you have
to fool the program to think there is no coprocessor. This is done with
"SET 87=N" at the prompt.

Note it is bad to use reals when one uses $N+, especially with $E+.
That is because the reals are first converted to doubles (or was it to
extended) and then they can be emulated. This is very slow.

...

Quote

>>  Also there is
>> the fact that your code does not work with emulation. I got -1 when I
>> tried integ(-1.5).

>This is true.  I forgot to mention that my code always rounds "towards
>the positive" for .5 values :-).  What is defined in the pascal doc's is
>rounds "away from zero" for the .5 cases.  Since I was "fixing" round I
>decided to do it "towards the positive".  It makes sense for the types
>of things that I do at work.

So you want to replace one strange behavior with another. Btw if that
really is a problem then maybe you should consider some other data type.
The nature of reals (in mathematical chance) is that if one picks a
random one the probability that the fraction is exactly 0.5 is zero. If
that really causes a major problem then maybe you should consider some
other data type. Especially if you are playing with money, do not use
reals with pennies as fractions.

Osmo

Re:Turbo Pascal and Reals and Integers


Quote
> Note it is bad to use reals

[...]

In my book it is bad to use reals, ever.  The nature of the work that I
do is signal processing.  It would be prohibitively slow to use real and
just plain silly.  I require that the users of my code have an 80x87.
It is not an unreasonable requirement in the field I am in.  This
discussion has not, in my mind, been about the real data type.  It is
about the inconsistency of round.  The fact that this code

var s:single;
begin
s:=2.5;
writeln (round(s):5:2,round(2.5):5:2);
end.
produces 2 3
is problematic.  Irregardles of the $E state.  

Quote

> So you want to replace one strange behavior with another.

The fact that round seems to round towards the even is also
problematic.   Someone _may_ care what kind of error is being introduced
by round.  
The round towards even introduces a "frequency modulation" error.  It
has mean error of 0.  That is one type.

The round away from 0 (your code using .5 for the negative fixup value)
has mean error of 0, but introduces a phase shift at the zero crossing.

The round toward the positive introduces a small DC error but reduces
the amount of FM.

Quote
>Btw if that
> really is a problem then maybe you should consider some other data type.

I HATE "real"'s.  I NEVER use it.  My initial response was for a poster
who had some questions about round.

Quote
> The nature of reals (in mathematical chance) is that if one picks a
> random one the probability that the fraction is exactly 0.5 is zero.

This is patently false.  Reals are discrete numbers.  Each real actually
represents a range of values that is a function of the number of bits
used to represent that type.  Since the value .5 actually represents a
range.  It has an area in the distribution of real numbers.  This yields
a non-zero chance of a .5 occurring.  

If you were using round(random(n)) to get integer values you would end
up with a slight bias towards even numbers.  If you were doing science,
or programming a slot machine you want to know about that.  Hell, in the
case of a slot machine it might even be illegal.

Quote
>Especially if you are playing with money, do not use
> reals with pennies as fractions.

agreed.

Quote
> Osmo

Ephram

Re:Turbo Pascal and Reals and Integers


Quote
Osmo Ronkanen wrote:

> Do not generalize from your personal use. Reals are very good for many
> uses.

> >var s:single;
> >begin
> >s:=2.5;
> >writeln (round(s):5:2,round(2.5):5:2);
> >end.
> >produces 2 3
> >is problematic.  Irregardles of the $E state.

[rationalization about why this happens deleted]

[description of the types of round deleted]

Quote
> Maybe you should have said these in your first message and not assumed
> that everyone knew it.

If you read my first post in this thread the point was that round
produces inconsistent results. It was not a discussion of why one might
care that they are inconsistent, the fact that they are should be enough
for people to take some notice.

as Horst Kraemer said in this thread

Quote
>This is a {*word*193} inconsistency (which I would call a bug) in all TP
>versions which support FPU types. It was know to Borland but they
>never corrected it.
> I mean reals in general i.e. including single, double and extended.

yes, so do I.  This inconsistency happens for all of them.

Quote
> In Mathematics there are no bits.

This is a red herring then.  What we are talking about is round and its
action in a digital computer programmed in Borland(tm) Pascal, where
there are bits.

Quote
> Now computer reals
> are a poor approximation of the reals in mathematics, but still if the
> rounding becomes a problem then I wonder are you using a correct data
> type.

They are what we have and we can decide if they are good enough with a
little knowledge.  I saw that the round towards even was a problem and I
fixed it for my own code (a correct data type now?).  The round towards
even seemd to me to be particularly egregious so I made mention of it.

Quote
> Are slot machines based on pseudo random numbers legal?

a) I believe that such beasts exist already.
and
b) The point really is if you use round(random*n) you do not end up with
a uniform distribution.  There will be a slight bias towards even #'s

Quote
> I'd use trunc() if I'd ever use reals.

agreed.  Trunc is the right function for this.

Quote

> Osmo

Ephram

Re:Turbo Pascal and Reals and Integers


Quote
>Subject: Re: Turbo Pascal and Reals and Integers
>From: Ephram Cohen <eph...@ear.berkeley.edu>
>Date: Sat, Nov 15, 1997 14:35 EST
>Message-id: <346DF975.59436...@ear.berkeley.edu>

>Osmo Ronkanen wrote:

>> In article <346CA276.AC611...@ear.berkeley.edu>,
>> Ephram Cohen  <eph...@ear.berkeley.edu> wrote:

>> >In the following code
>> >var  r : real;
>> >begin
>> >  writeln (round(-1.5));
>> >  writeln (round(-2.5));
>> >  r := -1.5; writeln (round(r));
>> >  r := -2.5; writeln (round(r));
>> >  r := 1.5; writeln (round(r));
>> >  r := 2.5; writeln (round(r));
>> >end.

>> >we get printed out
>> >-2
>> >-3
>> >-2
>> >-2  <= note this one.
>> >2
>> >2  <= note this one also.

>> I tried it and got:

>> -2
>> -3
>> -2
>> -3
>> 2
>> 3

>> Try running it with $N-.

>Whay would I possibly want to do this?  Floating point emulation in
>software has got to be significantly slower that using the hardware
>floating point.  Is this not true?  Are there some other benefits I do
>not know about?

>> It may be that the round is towards an even value.

>Possibly.

That's certainly right.  Most people don't know this, but Intel's coprocessor
 offers only 4 different ways of "rounding":

1. round toward nearest or even (default)
2. round up toward +inf
3. round down toward -inf
4. truncate towards 0

Therefore numbers like 2.5 are rounded to the nearest even integer----2.  AFAIK
 there is no actual coprocessor function/option for the "normal" way of
 rounding.

Quote
>What anoys me is that it does not do what is IMO
>mathematically expected.

But this is what science expected!  Believe it or not, the scientific
 convention for rounding numbers like 2.5 is toward the nearest even integer.
 I think the idea is either to minimize error (the ".5" numbers give the most
 error in rounding, which adds up when doing operations with rounded #s unless
 the "even rule" is used;
for example, when rounded mathematically, 2.5+1.5 = 4 becomes 3 + 2 = 5, while
 the even rounding gives 2 + 2 = 4...) or is just plain convention.  And
 floating-points are designed for scientific rather than mathematical purposes.
  Nevertheless, I must confess that I find this discrepancy between scientific
 and mathematical rounding to be annoying.

Quote
>What anoys me more is that there are different
>results with the software emulation v actual hardware.

I agree.  Apparently the programmers aren't aware of this even behavior either.

<snip>

- Show quoted text -

Quote
>> Osmo

>Ephram

Re:Turbo Pascal and Reals and Integers


In article <19971118214101.QAA09...@ladder02.news.aol.com>,

Quote
CBongChan <cbongc...@aol.com> wrote:

>That's certainly right.  Most people don't know this, but Intel's coprocessor
> offers only 4 different ways of "rounding":

>1. round toward nearest or even (default)
>2. round up toward +inf
>3. round down toward -inf
>4. truncate towards 0

>Therefore numbers like 2.5 are rounded to the nearest even integer----2.  AFAIK
> there is no actual coprocessor function/option for the "normal" way of
> rounding.

But aren't these modes for all fractions and not just x.5 type
fractions. So if one chooses rounding up, 2.1 becomes 3.

Quote

>But this is what science expected!  Believe it or not, the scientific
> convention for rounding numbers like 2.5 is toward the nearest even integer.
> I think the idea is either to minimize error (the ".5" numbers give the most
> error in rounding, which adds up when doing operations with rounded #s unless
> the "even rule" is used;
>for example, when rounded mathematically, 2.5+1.5 = 4 becomes 3 + 2 = 5, while
> the even rounding gives 2 + 2 = 4...) or is just plain convention.  And
> floating-points are designed for scientific rather than mathematical purposes.
>  Nevertheless, I must confess that I find this discrepancy between scientific
> and mathematical rounding to be annoying.

The issue is not so much that .5 gives the greatest error but to get
errors in large group of numbers to cancel each out. 0.1 cancels 0.9,
0.2 or 0.8 and so on. To cancel 0.5 out one has to round then up half a
time and down half a time. (That was a simplified example, computers
work with binaries and with greater accuracy)

Osmo

Re:Turbo Pascal and Reals and Integers


Quote
>Subject: Re: Turbo Pascal and Reals and Integers
>From: ronka...@cc.helsinki.fi (Osmo Ronkanen)
>Date: Tue, Nov 18, 1997 17:06 EST
>Message-id: <64t3gv$...@kruuna.Helsinki.FI>

>In article <19971118214101.QAA09...@ladder02.news.aol.com>,
>CBongChan <cbongc...@aol.com> wrote:

>>That's certainly right.  Most people don't know this, but Intel's
>coprocessor
>> offers only 4 different ways of "rounding":

>>1. round toward nearest or even (default)
>>2. round up toward +inf
>>3. round down toward -inf
>>4. truncate towards 0

>>Therefore numbers like 2.5 are rounded to the nearest even integer----2.
>AFAIK
>> there is no actual coprocessor function/option for the "normal" way of
>> rounding.

>But aren't these modes for all fractions and not just x.5 type
>fractions. So if one chooses rounding up, 2.1 becomes 3.

Yeah.  That's why I have rounding in quotes.  The four different modes are
selected via the Rouding Control Field in the Coprocessor Control Word.

<snip>

Other Threads