1. RE: BUG! Erratic for loop behavior
Rolf Schröder wrote:
> Andy Serpa wrote:
> > ...
> > ------------------------------
> > for i = 31.1 to 34.2 by .1 do
> > ? i
> > end for
> > ------------------------------
> > stops at 34.1 (!), NOT as expected.
> >
> Hi Andy,
>
> that's ok. Look at this:
>
> for i = 31.1 to 34.1 by 0.1 do
> printf(1,"%20.15f\n",i)
> end for
>
> and you will notice why: the decimal given value 0.1 is exactly
> representable in the computer for it has to stores it internally as an
> binary value with a limited number of bits. Actually, 0.1 (dec.) is has
> an unlimited binary representation: 0.0001100110011..... . This is the
> correct way to do it (have in mind that 31.1 and 34.1 are also not
> exactly representable!):
>
> for i = 311 to 341 by 1 do
> printf(1,"%20.15f\n",i/10)
> end for
>
Yeah, that's not really good enough for me -- .1 should be .1 in a loop.
The Euphoria manual even has an example under the FOR loop section
using a .3 "by" value... Is this also a "feature"?
2. RE: BUG! Erratic for loop behavior
Here's another example:
atom sum
sum = 60.0
for i = 1 to 45 do
sum += .1
end for
? sum
? equal(sum,64.5)
? (sum = 64.5)
Output is:
64.5
0
0
Please don't tell me this is desirable behavior. Explaining the cause
of the problem doesn't remove the problem. I am well aware of how
computers represent numbers but since I'm only dealing with one decimal
place I should get at least that much precision (actually, reverse that
-- I am getting too much precision) when doing comparsions...
Andy Serpa wrote:
>
> Rolf Schröder wrote:
> > Andy Serpa wrote:
> > > ...
> > > ------------------------------
> > > for i = 31.1 to 34.2 by .1 do
> > > ? i
> > > end for
> > > ------------------------------
> > > stops at 34.1 (!), NOT as expected.
> > >
> > Hi Andy,
> >
> > that's ok. Look at this:
> >
> > for i = 31.1 to 34.1 by 0.1 do
> > printf(1,"%20.15f\n",i)
> > end for
> >
> > and you will notice why: the decimal given value 0.1 is exactly
> > representable in the computer for it has to stores it internally as an
> > binary value with a limited number of bits. Actually, 0.1 (dec.) is has
> > an unlimited binary representation: 0.0001100110011..... . This is the
> > correct way to do it (have in mind that 31.1 and 34.1 are also not
> > exactly representable!):
> >
> > for i = 311 to 341 by 1 do
> > printf(1,"%20.15f\n",i/10)
> > end for
> >
>
> Yeah, that's not really good enough for me -- .1 should be .1 in a loop.
> The Euphoria manual even has an example under the FOR loop section
> using a .3 "by" value... Is this also a "feature"?
>
>
3. RE: BUG! Erratic for loop behavior
Do a search for "floating point precision" in the mailing list archives.
Chris
Andy Serpa wrote:
>
> Rolf Schröder wrote:
> > Andy Serpa wrote:
> > > ...
> > > ------------------------------
> > > for i = 31.1 to 34.2 by .1 do
> > > ? i
> > > end for
> > > ------------------------------
> > > stops at 34.1 (!), NOT as expected.
> > >
> > Hi Andy,
> >
> > that's ok. Look at this:
> >
> > for i = 31.1 to 34.1 by 0.1 do
> > printf(1,"%20.15f\n",i)
> > end for
> >
> > and you will notice why: the decimal given value 0.1 is exactly
> > representable in the computer for it has to stores it internally as an
> > binary value with a limited number of bits. Actually, 0.1 (dec.) is has
> > an unlimited binary representation: 0.0001100110011..... . This is the
> > correct way to do it (have in mind that 31.1 and 34.1 are also not
> > exactly representable!):
> >
> > for i = 311 to 341 by 1 do
> > printf(1,"%20.15f\n",i/10)
> > end for
> >
>
> Yeah, that's not really good enough for me -- .1 should be .1 in a loop.
> The Euphoria manual even has an example under the FOR loop section
> using a .3 "by" value... Is this also a "feature"?
>
>
4. RE: BUG! Erratic for loop behavior
Chris Bensler wrote:
> Do a search for "floating point precision" in the mailing list archives.
>
Ok, I guess there's nothing to be done about it. I just don't
understand why the effect is allowed to become cumulative...
> Chris
>
> Andy Serpa wrote:
> >
> > Rolf Schröder wrote:
> > > Andy Serpa wrote:
> > > > ...
> > > > ------------------------------
> > > > for i = 31.1 to 34.2 by .1 do
> > > > ? i
> > > > end for
> > > > ------------------------------
> > > > stops at 34.1 (!), NOT as expected.
> > > >
> > > Hi Andy,
> > >
> > > that's ok. Look at this:
> > >
> > > for i = 31.1 to 34.1 by 0.1 do
> > > printf(1,"%20.15f\n",i)
> > > end for
> > >
> > > and you will notice why: the decimal given value 0.1 is exactly
> > > representable in the computer for it has to stores it internally as an
> > > binary value with a limited number of bits. Actually, 0.1 (dec.) is has
> > > an unlimited binary representation: 0.0001100110011..... . This is the
> > > correct way to do it (have in mind that 31.1 and 34.1 are also not
> > > exactly representable!):
> > >
> > > for i = 311 to 341 by 1 do
> > > printf(1,"%20.15f\n",i/10)
> > > end for
> > >
> >
> > Yeah, that's not really good enough for me -- .1 should be .1 in a loop.
> > The Euphoria manual even has an example under the FOR loop section
> > using a .3 "by" value... Is this also a "feature"?
> >
> >
5. RE: BUG! Erratic for loop behavior
There is no reason that a loop whould need floating point math for it's
values.
I can't see it being any faster.
Eu automatically uses floating point as soon as it encounters a decimal
value.
I don't think it should apply for loops.
Chris
Andy Serpa wrote:
>
> Chris Bensler wrote:
> > Do a search for "floating point precision" in the mailing list archives.
> >
>
> Ok, I guess there's nothing to be done about it. I just don't
> understand why the effect is allowed to become cumulative...
>
>
> > Chris
> >
> > Andy Serpa wrote:
> > >
> > > Rolf Schröder wrote:
> > > > Andy Serpa wrote:
> > > > > ...
> > > > > ------------------------------
> > > > > for i = 31.1 to 34.2 by .1 do
> > > > > ? i
> > > > > end for
> > > > > ------------------------------
> > > > > stops at 34.1 (!), NOT as expected.
> > > > >
> > > > Hi Andy,
> > > >
> > > > that's ok. Look at this:
> > > >
> > > > for i = 31.1 to 34.1 by 0.1 do
> > > > printf(1,"%20.15f\n",i)
> > > > end for
> > > >
> > > > and you will notice why: the decimal given value 0.1 is exactly
> > > > representable in the computer for it has to stores it internally as an
> > > > binary value with a limited number of bits. Actually, 0.1 (dec.) is has
> > > > an unlimited binary representation: 0.0001100110011..... . This is the
> > > > correct way to do it (have in mind that 31.1 and 34.1 are also not
> > > > exactly representable!):
> > > >
> > > > for i = 311 to 341 by 1 do
> > > > printf(1,"%20.15f\n",i/10)
> > > > end for
> > > >
> > >
> > > Yeah, that's not really good enough for me -- .1 should be .1 in a loop.
> > > The Euphoria manual even has an example under the FOR loop section
> > > using a .3 "by" value... Is this also a "feature"?
> > >
> > >
6. RE: BUG! Erratic for loop behavior
> >
> >Do a search for "floating point precision" in the mailing list archives.
>
Look for the ones written by Robert Craig. I guess I knew vaguely of
this problem, but didn't realize how quickly you can come up with a
gross error. Basically, adding together a bunch of floating-point
numbers is completely inaccurate! How nice...
7. RE: BUG! Erratic for loop behavior
for i = var1 to var 2 by var3 do
end for
how much should the vars be multiplied by?
Chris
Dan Moyer wrote:
> Andy,
>
> Although I assume this is at least obvious, you could just do this:
>
> for i = 10*31.1 to 10*34.2 do
> ?i/10
> end for
>
> Same for whatever max "level" of floating point you have, ie, if *any*
> value
> goes out to .001,multiply all by 1000, then divide, etc.
>
> Maybe there's some good reason that doesn't occur to me offhand why this
> won't work?
>
> Dan Moyer
>
> ----- Original Message -----
> From: "Andy Serpa" <renegade at earthling.net>
> To: "EUforum" <EUforum at topica.com>
> Sent: Saturday, March 23, 2002 11:19 AM
> Subject: BUG! Erratic for loop behavior
>
>
> > Hello,
> >
> >
> > The output of this loop:
> > ------------------------------
> > for i = 9.4 to 10.0 by .1 do
> > ? i
> > end for
> > ------------------------------
> > stops at 10, as expected.
> >
> >
> > The output of this loop:
> > ------------------------------
> > for i = 31.1 to 34.2 by .1 do
> > ? i
> > end for
> > ------------------------------
> > stops at 34.1 (!), NOT as expected.
> >
> >
> > The output of this loop:
> > ------------------------------
> > for i = 131.1 to 134.2 by .1 do
> > ? i
> > end for
> > ------------------------------
> > stops at 134.2, as expected.
> >
> >
> > The output of this loop:
> > ------------------------------
> > for i = 60.0 to 64.5 by .1 do
> > ? i
> > end for
> > ------------------------------
> > stops at 64.4, NOT as expected.
> >
> >
> > I've verified this on exw.exe & ex.exe, as well as translated to C. It
> > looks like an outright bug to me.
> >
>
8. RE: BUG! Erratic for loop behavior
function magnify(atom a)
sequence str
integer f
str = sprintf("%f",a)
f = find('.',str)
if f then
a *= power(10,length(str)-f)
end if
return a
end function
It works for up to 6 decimal places.
34.1234567 will not be fully magnified.
Chris
Dan Moyer wrote:
> off the top of my head:
> change the vars to sequence, check for '.', count how many to right of
> '.',
> multiply by 10 to the how many for the MAX number in any var?
>
> Dan
>
> ----- Original Message -----
> From: "Chris Bensler" <bensler at mail.com>
> To: "EUforum" <EUforum at topica.com>
> Sent: Saturday, March 23, 2002 9:02 PM
> Subject: RE: BUG! Erratic for loop behavior
>
>
> >
> > for i = var1 to var 2 by var3 do
> > end for
> >
> > how much should the vars be multiplied by?
> >
> > Chris
> >
> > Dan Moyer wrote:
> > > Andy,
> > >
> > > Although I assume this is at least obvious, you could just do this:
> > >
> > > for i = 10*31.1 to 10*34.2 do
> > > ?i/10
> > > end for
> > >
> > > Same for whatever max "level" of floating point you have, ie, if *any*
> > > value
> > > goes out to .001,multiply all by 1000, then divide, etc.
> > >
> > > Maybe there's some good reason that doesn't occur to me offhand why this
> > > won't work?
> > >
> > > Dan Moyer
> > >
> > > ----- Original Message -----
> > > From: "Andy Serpa" <renegade at earthling.net>
> > > To: "EUforum" <EUforum at topica.com>
> > > Sent: Saturday, March 23, 2002 11:19 AM
> > > Subject: BUG! Erratic for loop behavior
> > >
> > >
> > > > Hello,
> > > >
> > > >
> > > > The output of this loop:
> > > > ------------------------------
> > > > for i = 9.4 to 10.0 by .1 do
> > > > ? i
> > > > end for
> > > > ------------------------------
> > > > stops at 10, as expected.
> > > >
> > > >
> > > > The output of this loop:
> > > > ------------------------------
> > > > for i = 31.1 to 34.2 by .1 do
> > > > ? i
> > > > end for
> > > > ------------------------------
> > > > stops at 34.1 (!), NOT as expected.
> > > >
> > > >
> > > > The output of this loop:
> > > > ------------------------------
> > > > for i = 131.1 to 134.2 by .1 do
> > > > ? i
> > > > end for
> > > > ------------------------------
> > > > stops at 134.2, as expected.
> > > >
> > > >
> > > > The output of this loop:
> > > > ------------------------------
> > > > for i = 60.0 to 64.5 by .1 do
> > > > ? i
> > > > end for
> > > > ------------------------------
> > > > stops at 64.4, NOT as expected.
> > > >
> > > >
> > > > I've verified this on exw.exe & ex.exe, as well as translated to C.
> It
> > > > looks like an outright bug to me.
> > > >
> > >
> >
> >
> >
>
>
>
9. RE: BUG! Erratic for loop behavior
Dan Moyer wrote:
> Andy,
>
> Although I assume this is at least obvious, you could just do this:
>
> for i = 10*31.1 to 10*34.2 do
> ?i/10
> end for
>
> Same for whatever max "level" of floating point you have, ie, if *any*
> value
> goes out to .001,multiply all by 1000, then divide, etc.
>
> Maybe there's some good reason that doesn't occur to me offhand why this
> won't work?
>
No, that works fine for getting this particular loop to work. But the
problem outside of a loop as well. Let's say you make an application
that adds and subtracts dollars & cents a lot.
.1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 does not equal 1 -- just try
it. It will display as one if you print it, but if you do this:
x = .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1
if x = 1 then
puts(1,"TRUE.")
else
puts(1,"FALSE.")
end if
It will come up false.
So if you have a program that does any kind of floating-point
calculations, and then check to see if a particular value = some other
value, you'll often get the wrong answer.
I just didn't realize before it was so serious. Those of use who don't
come from a low-level programming background or don't have a lot of
hardware knowledge aren't told this anywhere. It really ought to be in
the manual....
10. RE: BUG! Erratic for loop behavior
> .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 does not equal 1 -- just try
> it. It will display as one if you print it, but if you do this:
>
> x = .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1
Oops. One ".1" short, but you get the point...
11. RE: BUG! Erratic for loop behavior
While researching 3d math and related things, it was often recommended
to use fixed point integer math instead of floating point.
Most of the references were fairly old, predating the coprocessor, so
suggested fixed point as a faster alternative. Some recognized the use
of an FPU, but still recommended fixed point as a more accurate method.
I never did figure out how fixed point math works.
How much slower is fixed point math in comparison?
Chris
Andy Serpa wrote:
>
> Dan Moyer wrote:
> > Andy,
> >
> > Although I assume this is at least obvious, you could just do this:
> >
> > for i = 10*31.1 to 10*34.2 do
> > ?i/10
> > end for
> >
> > Same for whatever max "level" of floating point you have, ie, if *any*
> > value
> > goes out to .001,multiply all by 1000, then divide, etc.
> >
>
> > Maybe there's some good reason that doesn't occur to me offhand why this
> > won't work?
> >
>
> No, that works fine for getting this particular loop to work. But the
> problem outside of a loop as well. Let's say you make an application
> that adds and subtracts dollars & cents a lot.
>
> .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 does not equal 1 -- just try
> it. It will display as one if you print it, but if you do this:
>
> x = .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1
> if x = 1 then
> puts(1,"TRUE.")
> else
> puts(1,"FALSE.")
> end if
>
> It will come up false.
>
> So if you have a program that does any kind of floating-point
> calculations, and then check to see if a particular value = some other
> value, you'll often get the wrong answer.
>
> I just didn't realize before it was so serious. Those of use who don't
> come from a low-level programming background or don't have a lot of
> hardware knowledge aren't told this anywhere. It really ought to be in
> the manual....
>
>
>
12. RE: BUG! Erratic for loop behavior
If you change %f to %.10g it's accurate up to 8 decimal places.
I think that's fairly accurate, but when yer talking math, it's not
precise.
Chris
Chris Bensler wrote:
> function magnify(atom a)
> sequence str
> integer f
> str = sprintf("%f",a)
> f = find('.',str)
> if f then
> a *= power(10,length(str)-f)
> end if
> return a
> end function
>
> It works for up to 6 decimal places.
> 34.1234567 will not be fully magnified.
>
>
> Chris
>
>
> Dan Moyer wrote:
> > off the top of my head:
> > change the vars to sequence, check for '.', count how many to right of
> > '.',
> > multiply by 10 to the how many for the MAX number in any var?
> >
> > Dan
> >
> > ----- Original Message -----
> > From: "Chris Bensler" <bensler at mail.com>
> > To: "EUforum" <EUforum at topica.com>
> > Sent: Saturday, March 23, 2002 9:02 PM
> > Subject: RE: BUG! Erratic for loop behavior
> >
> >
> > > for i = var1 to var 2 by var3 do
> > > end for
> > >
> > > how much should the vars be multiplied by?
> > >
> > > Chris
> > >
> > > Dan Moyer wrote:
> > > > Andy,
> > > >
> > > > Although I assume this is at least obvious, you could just do this:
> > > >
> > > > for i = 10*31.1 to 10*34.2 do
> > > > ?i/10
> > > > end for
> > > >
> > > > Same for whatever max "level" of floating point you have, ie, if *any*
> > > > value
> > > > goes out to .001,multiply all by 1000, then divide, etc.
> > > >
> > > > Maybe there's some good reason that doesn't occur to me offhand why this
> > > > won't work?
> > > >
> > > > Dan Moyer
> > > >
> > > > ----- Original Message -----
> > > > From: "Andy Serpa" <renegade at earthling.net>
> > > > To: "EUforum" <EUforum at topica.com>
> > > > Sent: Saturday, March 23, 2002 11:19 AM
> > > > Subject: BUG! Erratic for loop behavior
> > > >
> > > >
> > > > > Hello,
> > > > >
> > > > >
> > > > > The output of this loop:
> > > > > ------------------------------
> > > > > for i = 9.4 to 10.0 by .1 do
> > > > > ? i
> > > > > end for
> > > > > ------------------------------
> > > > > stops at 10, as expected.
> > > > >
> > > > >
> > > > > The output of this loop:
> > > > > ------------------------------
> > > > > for i = 31.1 to 34.2 by .1 do
> > > > > ? i
> > > > > end for
> > > > > ------------------------------
> > > > > stops at 34.1 (!), NOT as expected.
> > > > >
> > > > >
> > > > > The output of this loop:
> > > > > ------------------------------
> > > > > for i = 131.1 to 134.2 by .1 do
> > > > > ? i
> > > > > end for
> > > > > ------------------------------
> > > > > stops at 134.2, as expected.
> > > > >
> > > > >
> > > > > The output of this loop:
> > > > > ------------------------------
> > > > > for i = 60.0 to 64.5 by .1 do
> > > > > ? i
<snip>
13. RE: BUG! Erratic for loop behavior
How does atom_to_float help?
sequence x x= atom_to_float32(0.1)
? x
? float32_to_atom(x+x+x+x+x+x+x+x+x+x)
How do other languages deal with the general use of decimals?
Chris
Andy Serpa wrote:
> > .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 does not equal 1 -- just try
> > it. It will display as one if you print it, but if you do this:
> >
> > x = .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1
>
> Oops. One ".1" short, but you get the point...
>
>
14. RE: BUG! Erratic for loop behavior
I just did some further testing, and it seems that magnifying a decimal
value doesn't help either.
? magnify(0.12345678901) = 12345678901 -- 0
? magnify(0.12345678901) = 123456789 -- 0
? magnify(0.12345678901) = 12345679 -- 0
This seems like a devastating problem. We use fractional numbers all the
time. How is it possible that it doesn't show up more often?
Do we need to resort to binary math? Would that even help?
What can be done to ensure that my program is calculating the math
properly?
Chris
Chris Bensler wrote:
> How does atom_to_float help?
>
>
> sequence x x= atom_to_float32(0.1)
>
> ? x
> ? float32_to_atom(x+x+x+x+x+x+x+x+x+x)
>
>
> How do other languages deal with the general use of decimals?
>
> Chris
>
> Andy Serpa wrote:
> > > .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 does not equal 1 -- just try
> > > it. It will display as one if you print it, but if you do this:
> > >
> > > x = .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1
> >
> > Oops. One ".1" short, but you get the point...
> >
> >
15. RE: BUG! Erratic for loop behavior
I added rounding to the magnify function, and it seems to work all the
time now. Right up to 16 decimal places.
<CODE>
function round(atom a, integer place)
atom b
b = floor(a)
return b + ((a-b) >= (0.5*power(10,-place)))
end function
function magnify(atom a)
sequence str
integer f
str = sprintf("%.16g",a)
f = find('.',str)
if f then
a *= power(10,length(str)-f)
return round(a,0)
else
return a
end if
end function
<END CODE>
Chris
Chris Bensler wrote:
> I just did some further testing, and it seems that magnifying a decimal
> value doesn't help either.
>
> ? magnify(0.12345678901) = 12345678901 -- 0
> ? magnify(0.12345678901) = 123456789 -- 0
> ? magnify(0.12345678901) = 12345679 -- 0
>
> This seems like a devastating problem. We use fractional numbers all the
>
> time. How is it possible that it doesn't show up more often?
>
> Do we need to resort to binary math? Would that even help?
>
> What can be done to ensure that my program is calculating the math
> properly?
>
>
> Chris
>
>
> Chris Bensler wrote:
> > How does atom_to_float help?
> >
> >
> > sequence x x= atom_to_float32(0.1)
> >
> > ? x
> > ? float32_to_atom(x+x+x+x+x+x+x+x+x+x)
> >
> >
> > How do other languages deal with the general use of decimals?
> >
> > Chris
> >
> > Andy Serpa wrote:
> > > > .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 does not equal 1 -- just try
> > > > it. It will display as one if you print it, but if you do this:
> > > >
> > > > x = .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1
> > >
> > > Oops. One ".1" short, but you get the point...
> > >
> > >
>
>
>
16. RE: BUG! Erratic for loop behavior
jbrown1050 at yahoo.com wrote:
>
> --x+6KMIRAuhnl3hBn
> Content-Type: text/plain; charset=us-ascii
>
> I have a hack which works fairly well, depending on
> the accuracy you want.
> It is a big hack, and not a long-term solution, but at
> least it works.
>
> It works by converting a number to a string and back
> again.
> Also, it needs a modified get.e, else inf and nan
> tests dont work at all.
>
Hey, I didn't think of that -- what happens when you sprint() a nan?
17. RE: BUG! Erratic for loop behavior
- Posted by dm31 at uow.edu.au
Mar 24, 2002
floating numbers should not have a problem stored most decimals like
0.1 and 0.01 since they since they store it with a mantissa(in 0.1
this is 0001) and an exponent( it becames 1111 in two's comple') I
could be wrong, but I don't see why and atom wouldn't store decimals
in this way, I fact what other way is there.
Dan
> I just did some further testing, and it seems that magnifying a
decimal
> value doesn't help either.
>
> ? magnify(0.12345678901) = 12345678901 -- 0
> ? magnify(0.12345678901) = 123456789 -- 0
> ? magnify(0.12345678901) = 12345679 -- 0
>
> This seems like a devastating problem. We use fractional numbers all
the
> time. How is it possible that it doesn't show up more often?
>
> Do we need to resort to binary math? Would that even help?
>
> What can be done to ensure that my program is calculating the math
> properly?
>
>
> Chris
>
>
> Chris Bensler wrote:
> > How does atom_to_float help?
> >
> >
> > sequence x x= atom_to_float32(0.1)
> >
> > ? x
> > ? float32_to_atom(x+x+x+x+x+x+x+x+x+x)
> >
> >
> > How do other languages deal with the general use of decimals?
> >
> > Chris
> >
> > Andy Serpa wrote:
> > > > .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 does not equal 1 --
just try
> > > > it. It will display as one if you print it, but if you do
this:
> > > >
> > > > x = .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1
> > >
> > > Oops. One ".1" short, but you get the point...
> > >
> > >
>
>
18. RE: BUG! Erratic for loop behavior
On 24 Mar 2002, at 6:24, Andy Serpa wrote:
>
>
> Dan Moyer wrote:
> > Andy,
> >
> > Although I assume this is at least obvious, you could just do this:
> >
> > for i = 10*31.1 to 10*34.2 do
> > ?i/10
> > end for
> >
> > Same for whatever max "level" of floating point you have, ie, if *any*
> > value
> > goes out to .001,multiply all by 1000, then divide, etc.
> >
>
> > Maybe there's some good reason that doesn't occur to me offhand why this
> > won't work?
> >
>
> No, that works fine for getting this particular loop to work. But the
> problem outside of a loop as well. Let's say you make an application
> that adds and subtracts dollars & cents a lot.
>
> .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 does not equal 1 -- just try
> it. It will display as one if you print it, but if you do this:
>
> x = .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1
> if x = 1 then
> puts(1,"TRUE.")
> else
> puts(1,"FALSE.")
> end if
>
> It will come up false.
>
> So if you have a program that does any kind of floating-point
> calculations, and then check to see if a particular value = some other
> value, you'll often get the wrong answer.
Any money math, or astronomy, or anything that must be accurate, must
account for large numbers of digits, should use string math. Or else you will
be bouncing off the difference in number systems and hardware overflows at
the worst times.
Kat
19. RE: BUG! Erratic for loop behavior
On 25 Mar 2002, at 9:53, dm31 at uow.edu.au wrote:
>
> floating numbers should not have a problem stored most decimals like
> 0.1 and 0.01 since they since they store it with a mantissa(in 0.1
> this is 0001) and an exponent( it becames 1111 in two's comple') I
> could be wrong, but I don't see why and atom wouldn't store decimals
> in this way, I fact what other way is there.
That is one heck of a sentence! After 3 minutes, i am still re-reading it to see
if i really know what you meant.
Kat
20. RE: BUG! Erratic for loop behavior
- Posted by dm31 at uow.edu.au
Mar 24, 2002
> That is one heck of a sentence! After 3 minutes, i am still
re-reading it to see
> if i really know what you meant.
>
> Kat
Sorry Kat,
Early morning is not a good time for making sense.
What i'm saying is a floating point number is stored in two parts
1. the mantissa
2. the exponent
an example is the 0.1 is stored as 1 x 10^-1
thus the mantissa is 1 and the exponent is -1
so using a 8-bit float as an example 0.1 in binary is
0001 and 1111(-1 in 2's complement)
So storing numbers like 0.1, 0.3 and 0.01 completely accurately should
not be a problem. It is only a problem in 'larger' decimal numbers.
for i = 31.4 to 31.5 do... should work perfectly. Or am I just been
dumb?
Dan
21. RE: BUG! Erratic for loop behavior
On 25 Mar 2002, at 11:04, dm31 at uow.edu.au wrote:
>
> > That is one heck of a sentence! After 3 minutes, i am still
> re-reading it to see
> > if i really know what you meant.
> >
> > Kat
>
> Sorry Kat,
> Early morning is not a good time for making sense.
Same here. After 2am, there's no telling what i'll type.
> What i'm saying is a floating point number is stored in two parts
> 1. the mantissa
> 2. the exponent
>
> an example is the 0.1 is stored as 1 x 10^-1
> thus the mantissa is 1 and the exponent is -1
> so using a 8-bit float as an example 0.1 in binary is
>
> 0001 and 1111(-1 in 2's complement)
>
> So storing numbers like 0.1, 0.3 and 0.01 completely accurately should
> not be a problem. It is only a problem in 'larger' decimal numbers.
>
> for i = 31.4 to 31.5 do... should work perfectly. Or am I just been
> dumb?
I wouldn't use the word "dumb". But consider the fraction 1/3. in decimal it's
0.3333333333333333-> infinity. How can that be represented in binary? It
can't. It's only perfectly accurate in base3 or integer multiples of 3. I think
i
remember an experimental computer that used 3 voltage levels per bit, but it
was slow and buggy, and that's all i remember of it. Back in the 8087@1mhz
days, i considered using analog carry-forward lines in an adder using a
74F181, which would have beat the socks off any 8087 i ever saw, but by
today's standards, it would be insanely slow. As slow as string math. The
best i know of in hardware for decimal math is BCD encoded
representations, but atm i can't recall any hardware in use today that has it.
The 8087 didn't. The Turbo Pascal runtime math lib didn't have it. But i
ramble... i didn't sleep at all lastnite.
Kat
22. RE: BUG! Erratic for loop behavior
- Posted by dm31 at uow.edu.au
Mar 24, 2002
> > for i = 31.4 to 31.5 do... should work perfectly. Or am I just
been
> > dumb?
>
> I wouldn't use the word "dumb". But consider the fraction 1/3. in
decimal it's
> 0.3333333333333333-> infinity. How can that be represented in
binary? It
> can't. It's only perfectly accurate in base3 or integer multiples of
3. I think i
> remember an experimental computer that used 3 voltage levels per
bit, but it
> was slow and buggy, and that's all i remember of it. Back in the
8087@1mhz
Yeh I've heard of the trinary computer too, But trinary is still used.
Alot of cmos chips involved in security systems use trinary encoders.
I understand the 1/3, BUT the for loops that this thread started with
should still work because they can be represented!
23. RE: BUG! Erratic for loop behavior
- Posted by Henri.Goffin at sbs.be
Mar 29, 2002
Hi!
My 2P on the subject.
I wrote this little program (see under) to help visualize the floating point
(im-)precision in Eu floating point arithmetic.
Basically it just outputs the results of some simple calculations with a lot of
decimal positions but with 0's replaced by another char to improve readibility.
>From this you can see that there is fluctuating relative error on the order of
>10e-15 to 10e-16, sometimes positive, sometimes negative. By relative I mean the
>ratio of the error to the magnitude of the number represented. IOW if you make
>calculations with numbers on the order of 1 (say 1.5423/2.9997) you would expect
>an absolute error on the order of 1e-15 or 0.000000000000001, and with numbers in
>the millions the absolute error would be on the order of 1e-9 or 0.000000001
>(please count the 0's for me, i'm not sure).
My question to the specialists out there: is it what one would expect given that
it is claimed that Euphoria uses internally the 64-bit (double precision) IEEE
floating point arithmetic?
A challenge for the brave: write a program to see if the errors cancel out on
the average or if there is a risk of cumulative errors, i.e. that the 1e-15
_relative_ precision becomes, say 1e-9, if you compute the sum of a million
numbers.
Now let's come back to the original message from Andy. As shocking as it seems
at first sight this is completely normal. Don't forget that a for-loop contains
implicitely a check for equality (if <var>=<end value>) on each cycle. Now even
if Euphoria (or any other language) used 65536-bit precision floating point
arithmetic you would still be at risk. The exact number of executions of the loop
would still be uncertain. Why? Because the equality test is ultimately performed
by the hardware in a strictly bit-for-bit way. And as we have seen there is
always a chance that the internal representations of the current value of <var>
and of <end value> will differ in at least one bit and it does not matter if it
is the 65536-th one, the test will fail and you will get one cycle too much (or
too few).
The morale is: either use only integer values in for-loops or replace the
for-loop with a while-loop.
In the former case you would write:
"for i = 311 to 342 by 1" and use i/10 inside the loop or equivalently "for i =1
to 32" and use (i+310)/10
In the latter case the while loop would read:
i=31.1
while i < 34.3 do
i += .1
end while
Henri Goffin
-------< start >--------
include get.e
atom a
function replace_in_string(sequence s, object o, object n)
sequence so
if atom(o) then
so = repeat(o, length(s))
s += (s = so) * (n - o)
return s
else
for i = 1 to length(o) do
s = replace_in_string(s, o[i], n[i])
end for
return s
end if
end function
procedure Xprintf(atom nr, atom fl)
sequence xp
integer ix
xp = sprintf("%d\t%30.25f\n",{nr, fl})
ix = match(".", xp)
xp[ix+1..length(xp)] = replace_in_string(xp[ix+1..length(xp)], '0', '-')
puts(1,xp)
end procedure
for k = 1 to 100 do
system("cls",2)
printf(1,"\n\nk = %d\n",{k})
a = 0
for i = 1 to 40 do
Xprintf(i-1,a)
a += .3 * k
end for
a = wait_key()
end for