1. I Need Help

I was messing about with some code that extracts a number from another
number using the difference between a calculated real number and its
integer. I could not seem to get the expected answer.

I then wrote a bit of test code to see just what Euphoria was doing and I
don't get the result I expected either. I am not sure (being new to
Euphoria) if it is something I don't understand about how the language
works or if it is something else. I would appreciate any help I could get
in understanding Why the code included dose not give me the results I
expected.

Larry D. Poos
-[USMC (Retar{bks}{bks}ired) Havelock, NC]-
- Programming and System Consultant, LTAD Enterprises -
e-mail: ldpoos at juno.com
Fido: 1:3629/101.6

-- Begin code segment
-- Example of math problem
-- by Larry Poos
-- Thu 06-19-1997
--
atom x,z
sequence bool
bool = {"Fail","Pass"}

-- modulo congruence test
x = remainder(3,7)
printf(1,"\nmodulo test 1\n %s for  3mod7=%d\n",{bool[x=3],x})
z = remainder(10,7)
printf(1,"\nmodulo test 2\n %s for 10mod7=%d\n",{bool[z=3],z})

printf(1,"\nequality test %s\n",{bool[remainder(3,7)=remainder(10,7)]})

-- other tests
-- All numbers ending in .0 should display on screen
-- only 0, 19, and 4819 display in all three forms of the alogrithm
--
puts(1,"\nDivision by 1 test\n")
for l=0  to 10000  by .1  do
    if not remainder(l,1) then -- handle only if evenly divisable by 1
        printf(1," pass for %g floor=%g\n",{l,floor(l)})
    end if
end for
puts(1,"Fail for all between 0 and 10000 not listed\n")

puts(1,"\nFloor equality test\n")
for l=0  to 10000  by .1  do
    if floor(l)=l then  -- handle only if floor is equal to base number
        printf(1," pass for %e floor=%e\n",{l,floor(l)})
    end if
end for
puts(1,"Fail for all between 0 and 10000 not listed\n")

puts(1,"\nNumber equality test\n")
x=0
while x < 10000.1 do
    z=floor(x)
    if not(z!=x) then  -- handle only if equal
        printf(1," pass for %e floor=%e\n",{x,floor(x)})
    end if
    x=x+.1
end while
puts(1,"Fail for all between 0 and 10000 not listed\n")
-- end code segment

new topic     » topic index » view message » categorize

2. I Need Help

Larry D Poos writes several loops such as:
> for l=3D0  to 10000  by .1  do

There's a simple explanation for why you aren't getting the
results that you expect. The root of the problem is
that 0.1 cannot be represented in binary floating-point
form *exactly*. This means that if you add up ten 0.1's
you will *not* get 1.

Try the following statement in Euphoria:
? .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 - 1

You will not get 0. You will get -1.11e-016.
in other words a very very small number.

In QBasic you will get 1.49e-08, which is even worse.

Any language that uses IEEE floating-point is going
to have this problem. Intel hardware is based on IEEE,
so anyone who uses hardware floating-point on a PC (or most
other machines) is going to have this problem.

If you use Cobol, you will not see this problem
because Cobol uses decimal floating-point and so .1
*can* be represented exactly. So can .01. This makes
money calculations work out nicely in Cobol.

Conclusion: Don't count on floating-point calculations
to work out perfectly. Allow for a little bit of error
in your calculations. Be careful when you compare
floating-point results for equality.

Regards,
  Rob Craig
  Rapid Deployment Software

new topic     » goto parent     » topic index » view message » categorize

3. Re: I Need Help

> Try the following statement in Euphoria:
> ? .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 - 1
>
> You will not get 0. You will get -1.11e-016.
> in other words a very very small number.

i tried it and i actually did get zero

new topic     » goto parent     » topic index » view message » categorize

4. Re: I Need Help

On Thu, 19 Jun 1997 21:51:48 -0400 Robert Craig writes

>Larry D Poos writes several loops such as:
>> for l=3D0  to 10000  by .1  do
>
>There's a simple explanation for why you aren't getting the
>results that you expect. The root of the problem is
>that 0.1 cannot be represented in binary floating-point
>form *exactly*. This means that if you add up ten 0.1's
>you will *not* get 1.

I knew that. <G> Decimals must be of the form x/(n base 2) to convert
exactly. I am so used to using languages and programs that use decimal
floating point I did not even think of this. When I read the docs and
they stated floating point math I thought "decimal" not binary. My bust.

I am not sharp enough to write a language myself and I do appreciate your
personal response to the problems I have encountered while testing
Euphoria.

Larry D. Poos
-[USMC (Retar{bks}{bks}ired) Havelock, NC]-
- Programming and System Consultant, LTAD Enterprises -
e-mail: ldpoos at juno.com
Fido: 1:3629/101.6

new topic     » goto parent     » topic index » view message » categorize

5. Re: I Need Help

On Fri, 20 Jun 1997 11:05:51 +0000 Mike.Burrell at GEOCITIES.COM writes:
>> Try the following statement in Euphoria:
>> ? .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 - 1
>>
>> You will not get 0. You will get -1.11e-016.
>
>i tried it and i actually did get zero

What kind of machine did you try this on?

After reading Roberts reply to my post "I knew that!" came to mind.
Numbers to the right of the decimal when converted to 16 bit binary may
lose the least significant digits 0.1 base 10 when converted to binary
and back to base 10 actually evaluates to 0.0999755859375, an error of
2.4414e-5 This is probably close enough for most applications but would
put you about 14.6 miles off course over 10K miles. No problem for large
targets but if you need to be with in a few feet this might be a problem.
<BG> it will also give you a day or two error when calculating the
calendar date from a StarDate.

Larry D. Poos
-[USMC (Retar{bks}{bks}ired) Havelock, NC]-
- Programming and System Consultant, LTAD Enterprises -
e-mail: ldpoos at juno.com
Fido: 1:3629/101.6

new topic     » goto parent     » topic index » view message » categorize

6. Re: I Need Help

> On Fri, 20 Jun 1997 11:05:51 +0000 Mike.Burrell at GEOCITIES.COM writes:
> >> Try the following statement in Euphoria:
> >> ? .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 - 1
> >>
> >> You will not get 0. You will get -1.11e-016.
> >
> >i tried it and i actually did get zero
>
> What kind of machine did you try this on?

p pro on win nt 4

new topic     » goto parent     » topic index » view message » categorize

7. Re: I Need Help

> There's a simple explanation for why you aren't getting the
> results that you expect. The root of the problem is
> that 0.1 cannot be represented in binary floating-point
> form *exactly*. This means that if you add up ten 0.1's
> you will *not* get 1.
>
> Try the following statement in Euphoria:
> ? .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 - 1
>
> You will not get 0. You will get -1.11e-016.
> in other words a very very small number.

Here is a routine that will correct such errors up to 15 decimal
places:

function round(atom x)
    return floor(x*1e15+0.5)/1e15
end function

Maybe this will be useful to someone.

Regards,
               Michael Bolin

new topic     » goto parent     » topic index » view message » categorize

8. Re: I Need Help

>> There's a simple explanation for why you aren't getting the
>> results that you expect. The root of the problem is
>>that 0.1 cannot be represented in binary floating-point
>>form *exactly*. This means that if you add up ten 0.1's
>> you will *not* get 1.
>
>> Try the following statement in Euphoria:
>> ? .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 - 1
>>
>> You will not get 0. You will get -1.11e-016.
> >in other words a very very small number.

>Here is a routine that will correct such errors up to 15 decimal
>places:

>function round(atom x)
>    return floor(x*1e15+0.5)/1e15
>end function

>Maybe this will be useful to someone.

>Regards,
>               Michael Bolin

Hi Michael,

Unfortunately, this is not useful to me. If I implement it with:

fprint(1, "4.2%f", round(0.745))

what do you think I get? Well, it is 0.74! Strange enough, some of the
values x.xx5 round up in the correct way, but not all of them! Is this a
bug in my processor (P75), or in the 'binary floating point' routines?
I am puzzled over this for a long time already, as I want to do some exac=
t
financial calculating in Euphoria. Isn't this possible at all, or should =
I
maybe disable my math coprocessor?

Someone please answer me!

Ad Rienks

new topic     » goto parent     » topic index » view message » categorize

9. Re: I Need Help

On Sat, 21 Jun 1997 23:45:00 -0400 Ad Rienks <Ad_Rienks at COMPUSERVE.COM>
writes:

>financial calculating in Euphoria. Isn't this possible at all, or
>should I maybe disable my math coprocessor?
>
>Ad Rienks
>

Just how many places must your numbers be accurate
2, 3, 4, 5, 6?

function fix(atom a, integer p)
  --if p = 1 then
    --a = a * 10
  --elsif p = 2 then
    --a = a * 100
  --elsif p = 3 then
    --a = a * 1000
  --end if
  --return a
  return a * power(10, p)
end function

function unfix(atom a, integer p)
  --floor(a)
  --if p = 1 then
    --a = a / 10
  --elsif p = 2 then
    --a = a / 100
  --elsif p = 3 then
    --a = a / 1000
  --end if
  --return a
  return floor(a) / power(10, p)
end function

atom a, b, c

c = .0001
a = 0
for r = 1 to 1000
  a = a + c
end for
printf(1, "%f14", a)

b = 0
for r = 1 to 1000
  b = b + fix(c, 3)
end for
b = unfix(b, 3)
printf(1, "%f14", b)

Try these routines. the second value passed is accuracy.

--Lucius Lamar Hilley III
--  E-mail at luciuslhilleyiii at juno.com
--  I support transferring of files less than 60K.
--  I can Decode both UU and Base64 format.

new topic     » goto parent     » topic index » view message » categorize

10. Re: I Need Help

> Hi Michael,
>
> Unfortunately, this is not useful to me. If I implement it with:
>
> fprint(1, "4.2%f", round(0.745))
>
> what do you think I get? Well, it is 0.74! Strange enough, some of the
> values x.xx5 round up in the correct way, but not all of them! Is this a
> bug in my processor (P75), or in the 'binary floating point' routines?
> I am puzzled over this for a long time already, as I want to do some exac=
> t
> financial calculating in Euphoria. Isn't this possible at all, or should =
> I
> maybe disable my math coprocessor?

This is not a bug in my routine, it is another bug resulting from
binary floating point representation.

But I have just modified the function to allow a variable amount of
precision, and it will work in cases such as yours.

----------------------------------------------------
function round(atom x,atom precision)
    precision=power(10,precision)
    return floor(x*precision+.5)/precision
end function
----------------------------------------------------

Just call it with an atom value, and a number of decimal places to
round to. You can use values less than one:
If you use 0, it will round to the nearest integer. If you
use -1, it will round to the nearest 10. If -2, the nearest 100, etc.

Regards,
              Michael Bolin

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu