Main Page | Report this Page
Computers Forum Index  »  Computer Languages (Smalltalk)  »  Visualworks 7.5 fractionPart bug...
Page 1 of 2    Goto page 1, 2  Next

Visualworks 7.5 fractionPart bug...

Author Message
Aik-Siong...
Posted: Sat Oct 17, 2009 2:36 am
Guest
1000.0d log fractionPart.
gives 1.0d which is not a fraction.!!!

FYI, Cincom SupportWeb kept timing out on me.

All the best,
Aik-Siong Koh
 
Aik-Siong...
Posted: Sat Oct 17, 2009 2:59 am
Guest
The problem is probably in log.
1000.0d log = 3.0d.
returns false!!!

ASK
 
Joachim Geidel...
Posted: Sat Oct 17, 2009 11:03 am
Guest
The comment of Double>>#fractionPart clearly states "Answer a Double
whose value is the difference between the receiver and the receiver's
truncated value". So there's nothing wrong with #fractionPart.

Quote:
The problem is probably in log.
1000.0d log = 3.0d.
returns false!!!

There's nothing wrong with that. It is just an example for the fact
that logarithms are usually computed up to a certain precision, and
that the precision of Doubles is limited. The difference is really
small:
1000.0d log - 3.0d ==> -4.4408920985006d-16

Cheers,
Joachim Geidel
 
nicolas cellier...
Posted: Mon Oct 19, 2009 6:22 am
Guest
On 17 oct, 13:03, Joachim Geidel <joachim.gei... at (no spam) bluecarat.de> wrote:
Quote:
The comment of Double>>#fractionPart clearly states "Answer a Double
whose value is the difference between the receiver and the receiver's
truncated value". So there's nothing wrong with #fractionPart.

The problem is probably in log.
1000.0d log = 3.0d.
returns false!!!

There's nothing wrong with that. It is just an example for the fact
that logarithms are usually computed up to a certain precision, and
that the precision of Doubles is limited. The difference is really
small:
1000.0d log - 3.0d ==> -4.4408920985006d-16

Cheers,
Joachim Geidel

In other words,

1000.0d log fractionPart < 1. -> true
1000.0d log fractionPart - 1. -> -4.4408920985006d-16

What is misleading is that 1-4.4408920985006d-16 get printed rounded
as 1.0d...

Nicolas
 
Aik-Siong...
Posted: Mon Oct 19, 2009 8:28 pm
Guest
A few years back, Intel had to spend $500M to recall a bunch of
Pentium chips that has small errors. I think Cincom would do well to
look into this bug before J P Morgan loses a few million dollars in
their business because of the bug.

In mathematics, it is absolutely not acceptable for
1000.0d log to be anything but 3.0d.

I double the IEEE standard would allow that.

Aik-Siong Koh
 
Stefan Schmiedl...
Posted: Tue Oct 20, 2009 1:28 am
Guest
On Mon, 19 Oct 2009 13:28:20 -0700 (PDT)
Aik-Siong <askoh at (no spam) askoh.com> wrote:

Quote:
A few years back, Intel had to spend $500M to recall a bunch of
Pentium chips that has small errors. I think Cincom would do well to
look into this bug before J P Morgan loses a few million dollars in
their business because of the bug.

In mathematics, it is absolutely not acceptable for
1000.0d log to be anything but 3.0d.

In mathematics, log_10 1000 === 3,

In floating point arithmetic log_10(1000.0) lies in an interval
[ 3.0 - epsilon_1 , 3.0 + epsilon_2 ] with some implementation
dependent small epsilons.

Do not compare floating point values with = is one of the rules
I found helpful on every platform I have used in the last 20 years.
Especially not if it's a "manually written constant" against a
"computed value".

s.
 
Cesar Rabak...
Posted: Tue Oct 20, 2009 1:51 am
Guest
Aik-Siong escreveu:
Quote:
A few years back, Intel had to spend $500M to recall a bunch of
Pentium chips that has small errors. I think Cincom would do well to
look into this bug before J P Morgan loses a few million dollars in
their business because of the bug.

In mathematics, it is absolutely not acceptable for
1000.0d log to be anything but 3.0d.

I double the IEEE standard would allow that.

Aik-Siong,


What part of "it is not a bug" did you not understand? The fact you have
doubts about a standard allowing or not is not a very robust way to
enlighten yourself. . .

As the IEEE standard may be slightly hard to come by if you don't want
to pay for it or have access via some public library, I direct you to
nowadays very famous and instructive paper available in the Net:
http://docs.sun.com/source/806-3568/ncg_goldberg.html.

If you're in a haste, start reading from "System Aspects" on and then
read the whole paper again.

BTW, note that contrary to your beliefs, the FDIV Pentium problem was
indeed a bug as the error is much larger than the accuracy of the data
types involved (example taken from Wikipedia):

4195835.0/3145727.0 = 1.333 820 449 136 241 002 (Correct value)
4195835.0/3145727.0 = 1.333 739 068 902 037 589 (Value returned by
flawed Pentium)

whose difference is 8.13802342034134773288e-5 or one billion times
larger than your complaint!!
 
Aik-Siong...
Posted: Tue Oct 20, 2009 3:06 pm
Guest
1000.0d log fractionPart
gives 1.0d. It should be 0.0d. The error is not small. Is this a bug?

1000.0d floorLog: 10.0d
gives 2. It should be 3. Again the error is not small. Is this a bug?

1000.0d floorLog10
gives 3 which is correct.

I encountered the above problem while trying to get the base 10
mantissa of a number. How can I do that safely?

Thanks,
Aik-Siong Koh
 
Joachim Geidel...
Posted: Tue Oct 20, 2009 5:08 pm
Guest
On 20 Okt., 17:06, Aik-Siong <as... at (no spam) askoh.com> wrote:
Quote:
1000.0d log fractionPart
gives 1.0d. It should be 0.0d. The error is not small. Is this a bug?

1000.0d floorLog: 10.0d
gives 2. It should be 3. Again the error is not small. Is this a bug?

1000.0d floorLog10
gives 3 which is correct.

I encountered the above problem while trying to get the base 10
mantissa of a number. How can I do that safely?

There is no way to do this "safely" in general. In this particular
case, rounding or truncating have the effect of inflating any very
small error (which is inherent to floating point arithmetic and cannot
be avoided) to an error of 1.0. You will have to look into the
implementation, and get the intermediate results before applying
floor / rounded / truncated. Then, you can try to do it differently.
You can find lots of material on the error propagation in floating
point arithmetics by searching the net, e.g.
http://www.google.de/search?q=floating+point+error+propagation
Generations of mathematicians have tackled this kind of problem, so
there is plenty of literature available. I even recall a Pascal
dialect which used interval arithmetic to determine the maximal errors
in floating point operations (I faintly remember that it was a group
at the University of Karlsruhe, Germany, who implemented this).

That said, the safest way to avoid floating point errors is not to use
floating point arithmetic in the first place, if that's possible.

Joachim Geidel
 
Cesar Rabak...
Posted: Wed Oct 21, 2009 1:11 am
Guest
Aik-Siong escreveu:
Quote:
1000.0d log fractionPart
gives 1.0d. It should be 0.0d. The error is not small. Is this a bug?


Your perception of the problem it that it is a bug, however, the
implementation of this method is (in Double it calls super, but the
effect is):

Double>>fractionPart
"Answer a Number whose value is the difference between the
receiver and the receiver's truncated value. "

^self - self truncated

Now how truncated works?

Double>>truncated
"Answer a SmallInteger equal to the value of the receive
without its fractional part. Fail if the truncated value be
represented as a SmallInteger. In that case, the code below
will compute a LargeInteger truncated value"

<primitive: 571>
| max quo rem |
max := SmallInteger maxVal // 2 + 1.
quo := self quo: max asDouble.
rem := self - (quo * max asDouble). "in-line rem to avoid
exponential number of quos"
^quo * max + rem truncated

If you care to check, you'll see that 1000.0d log truncated returns 2
(because 1000.0d log - 3 == -4.4408920985006d-16).


Quote:
1000.0d floorLog: 10.0d
gives 2. It should be 3. Again the error is not small. Is this a bug?


Same issue, Number>>floorLog: uses Number>>floor which uses truncated.

Quote:
1000.0d floorLog10
gives 3 which is correct.


As this method uses a primitive, it may be that results are done all in
the math coprocessor where some more guard bits maintain the precision
before sending the result.

Quote:
I encountered the above problem while trying to get the base 10
mantissa of a number. How can I do that safely?

Unfortunately as Joachim observes there are a few methods you can try
but they're specific for each case.

My bet would be to do something like (you may try use rounded instead):

(1000.0d truncated) floorLog: 10.0d and (1000.0d truncated) log
fractionPart, and see if the errors are amenable with this approach.

HTH

--
Cesar Rabak
GNU/Linux User 52247.
Get counted: http://counter.li.org/
 
Andy Bower...
Posted: Wed Oct 21, 2009 1:52 am
Guest
BTW,

Quote:
1000.0 floorLog: 10.0. -> 2.

I accept that this Dolphin result is in error but at least #fractionPart
is okay.

Best regards

Andy Bower
 
Andy Bower...
Posted: Wed Oct 21, 2009 1:52 am
Guest
Cesar, Aik-Siong,


Quote:
Aik-Siong escreveu:
1000.0d log fractionPart
gives 1.0d. It should be 0.0d. The error is not small. Is this a bug?



Frankly, I'd agree and say it was a bug. Whilst I know that comparing
floating point numbers can be tricky, in Dolphin:

1000.0 log fractionPart0. -> 0.

1000.0 floorLog: 10.0. -> 2.

1000.0 floorLog10. -> 3

If Dolphin can do it without issues I don't see why VisualWorks can't.

Best regards

Andy Bower

Quote:
Your perception of the problem it that it is a bug, however, the
implementation of this method is (in Double it calls super, but the
effect is):

Double>>fractionPart
"Answer a Number whose value is the difference between the
receiver and the receiver's truncated value. "

^self - self truncated

Now how truncated works?

Double>>truncated
"Answer a SmallInteger equal to the value of the receive
without its fractional part. Fail if the truncated value be
represented as a SmallInteger. In that case, the code below
will compute a LargeInteger truncated value"

primitive: 571
| max quo rem |
max := SmallInteger maxVal // 2 + 1.
quo := self quo: max asDouble.
rem := self - (quo * max asDouble). "in-line rem to avoid
exponential number of quos"
^quo * max + rem truncated

If you care to check, you'll see that 1000.0d log truncated returns 2
(because 1000.0d log - 3 == -4.4408920985006d-16).


1000.0d floorLog: 10.0d
gives 2. It should be 3. Again the error is not small. Is this a bug?


Same issue, Number>>floorLog: uses Number>>floor which uses truncated.

1000.0d floorLog10
gives 3 which is correct.


As this method uses a primitive, it may be that results are done all in
the math coprocessor where some more guard bits maintain the precision
before sending the result.

I encountered the above problem while trying to get the base 10
mantissa of a number. How can I do that safely?

Unfortunately as Joachim observes there are a few methods you can try
but they're specific for each case.

My bet would be to do something like (you may try use rounded instead):

(1000.0d truncated) floorLog: 10.0d and (1000.0d truncated) log
fractionPart, and see if the errors are amenable with this approach.

HTH
 
Cesar Rabak...
Posted: Wed Oct 21, 2009 5:16 am
Guest
Andy Bower escreveu:
Quote:
BTW,

1000.0 floorLog: 10.0. -> 2.

I accept that this Dolphin result is in error but at least #fractionPart
is okay.

Best regards

OK Andy!


Now we get back to square one! Given enough test cases it will fail in
border cases, perhaps different from other dialects, but still the same
thing.

Joachim's post still points to the broad answer.
 
Andy Bower...
Posted: Wed Oct 21, 2009 1:55 pm
Guest
Cesar,

Quote:
1000.0 floorLog: 10.0. -> 2.

I accept that this Dolphin result is in error but at least
#fractionPart is okay.

OK Andy!

Now we get back to square one! Given enough test cases it will fail in
border cases, perhaps different from other dialects, but still the same
thing.

Joachim's post still points to the broad answer.

Okay, I take it back. I've spent a bit of time looking into the Dolphin
implementation and I can see that (as you predicted) it isn't an easy
fix and using discontinuous functions like floor and round on calculated
floating values is the problem. Actually, I came across just the same
issue in some tests I wrote the other week and never found a solution.
I should have remembered that and piped down!

Sorry for the interjection - I'm back under my rock now.

Best regards

Andy Bower
 
Cesar Rabak...
Posted: Wed Oct 21, 2009 11:23 pm
Guest
Andy Bower escreveu:
Quote:
Cesar,

1000.0 floorLog: 10.0. -> 2.

I accept that this Dolphin result is in error but at least
#fractionPart is okay.

OK Andy!

Now we get back to square one! Given enough test cases it will fail in
border cases, perhaps different from other dialects, but still the
same thing.

Joachim's post still points to the broad answer.

Okay, I take it back. I've spent a bit of time looking into the Dolphin
implementation and I can see that (as you predicted) it isn't an easy
fix and using discontinuous functions like floor and round on calculated
floating values is the problem.

Yes, Smalltalk with its beautiful Number class that works like a charm
in the integral cases (what Smalltalker that doesn't know the famous
factorial example?) rises the level of expectations w.r.t. the other
numerical issues.

Quote:
Actually, I came across just the same
issue in some tests I wrote the other week and never found a solution. I
should have remembered that and piped down!

Only making mistakes you become wise!

Quote:

Sorry for the interjection - I'm back under my rock now.

We're here to share info.

Regards,

--
Cesar Rabak
GNU/Linux User 52247.
Get counted: http://counter.li.org/
 
 
Page 1 of 2    Goto page 1, 2  Next
All times are GMT
The time now is Wed Dec 02, 2009 10:41 am