Why, Speccy?

edited January 2013 in Sinclair Miscellaneous
OK, wanna see something strange?

Go to your Spectrum (or Spectrum emulator), and type

PRINT 10-100*0.1

:-o:-o:-o

Why???
Post edited by memrah on

Comments

  • edited January 2013
    It's the usual rounding error resulting from the fact that Speccy isn't calculating in base 10. 0.37252903E-9 is 0.00000000037252903, which isn't that far away from the correct answer :-) The problem would normally be disguised if the number wasn't so small, i.e. for some calculation with a result of 1.00000000037252903 only the 8 most significant digits would be kept and the rounding error would disappear.
  • edited January 2013
    The same as:

    IF (3/10)<>0.3 THEN PRINT "OUCH!"

    It happens that in base 10, 0.3 is a finite exact number, but in base 2, it's mantisa representation is a periodic number.
    001100110011001100...............

    As 3/10 is an operation subject to rounding on its least significant bit, a comparison like the above one will surely fail, not only in the Spectrum but in any computer and programming language using floating point scheme for decimal numbers (I wonder if COBOL, which is not based on floating point, will success in this test).

    And this is why you should avoid comparing two floating expressions using just the "equal to" or "different to" operators. Best use >= or <= .
  • edited January 2013
    I kinda hate to say this but I tried both the above comparison and 10-100*0.1 on two emulators, a 64 emulator and a QL emulator. They both returned correct results.. Hmmm
  • edited January 2013
    Different platforms, different results. What's your point? If you run enough test cases, you'll always be able to find one where your "favourite" platform does better than others.
  • edited January 2013
    memrah wrote: »
    I kinda hate to say this but I tried both the above comparison and 10-100*0.1 on two emulators, a 64 emulator and a QL emulator. They both returned correct results.. Hmmm
    I hate to say this but "PRINT 1/3-1/6-1/6" gives strange results on 64 and just 0 on the spec... Hmmm
  • edited January 2013
    35+ year old fanboys behaving like kiddos... Hmmm :D
  • edited January 2013
    Rounding errors are neither here nor there. If you want something really strange, try taking a square root on an early ZX81.
  • edited January 2013
    Timmy wrote: »
    "PRINT 1/3-1/6-1/6" gives strange results on 64 and just 0 on the spec... Hmmm

    HAHAHAHAHA Stupid 64. :-P:-P


    PS. QL passes this test. Sam Coupe fails.
  • edited January 2013
    The same as:

    IF (3/10)<>0.3 THEN PRINT "OUCH!"

    ... a comparison like the above one will surely fail, not only in the Spectrum but in any computer and programming language using floating point scheme for decimal numbers..

    (3/10)==0.3

    returns False in C#. (maybe it's because of type declaration defaulted to int?)

    So we should avoid floating point comparisons? But this will ruin all the fun :)

    I still don't understand mantissa representation problem, isn't both 0.3 and result of 3/10 represented with mantissa/exponent style? Why they are different?
  • edited January 2013
    not as good as the pentium P5s that had an actual bug baked into the silicon http://en.wikipedia.org/wiki/Pentium_FDIV_bug :smile:

    or the infamous subtraction bug in microsoft calculator.
  • edited January 2013
    I hope computers onboard space shuttles, missile guidance systems or life support units don't make such mistakes
  • edited January 2013
    Arda wrote: »
    I still don't understand mantissa representation problem, isn't both 0.3 and result of 3/10 represented with mantissa/exponent style? Why they are different?

    Doing the same conversions that are done by the Spectrum should clarify the reason for the discrepancy.
    0.3  = 7f 19 99 99 99
    3    = 00 00 03 00 00
    10   = 00 00 0a 00 00
    3/10 = 7f 19 99 99 9a
    
    Hence 0.3 <> 3/10.

    Dividing by reciprocals can help: 10-100/(1/0.1) gives zero.

    The number 3 is a tricky customer; eg.:
    0.3 * 10  =  3  =  82 3f ff ff ff
    3/10 * 10 =  3  =  82 40 00 00 01
    10 * 3/10 =  3  =  00 00 03 00 00
    
    So they're all equal to three but all different from each other!
  • edited January 2013
    memrah wrote: »
    I hope computers onboard space shuttles, missile guidance systems or life support units don't make such mistakes

    The error here is programmer error: you should never compare floating point numbers directly, but instead to within a known epsilon.
  • edited January 2013
    E
    memrah wrote: »
    I hope computers onboard space shuttles, missile guidance systems or life support units don't make such mistakes


    Actually there's a well known report on a bug found in a rocket firmware all programmed in ADA. It caused the rocket to explode 36s after launch blowing away everything it had within it, like expensive satellites.
  • edited January 2013
    memrah wrote: »
    I hope computers onboard space shuttles, missile guidance systems or life support units don't make such mistakes

    No, they usually make different even worse floating point mistakes...
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited January 2013
    No, they usually make different even worse floating point mistakes...

    This classic text ought to be read by every engineer in the world (IMHO): Personal Observations on Reliability of Shuttle, by Richard P. Feynman.
  • edited January 2013
    Applying the reciprocal calculation to both problems (posts #1 & #3) eliminates the error.

    Instead of a - b * 0.1 use a - b / (1/0.1) .

    Instead of 0.n <> n/10 use 0.n <> n * (1/10) .

    Where a*10=b and n=n they both return zero. The () are essential, even in the second example where they could be expected not to make any difference.

    The error is introduced by the two elements in each expression having slightly different values in the last mantissa byte. The alternative versions wangle it so that the last byte works out the same.
  • edited January 2013
    Don't you think that the topic question sounds too dramatic if we consider the subject? ;)
  • edited January 2013
    zx81 wrote: »
    This classic text ought to be read by every engineer in the world (IMHO): Personal Observations on Reliability of Shuttle, by Richard P. Feynman.

    Excellent text!

    It perfectly illustrates that people rarely run tests using a truly scientific approach, to really find out if an hypothesis is correct. Instead, they run tests to find enough "evidence" to claim whatever they prefer to be true, quite often adapting their criteria until it "fits". Another somewhat similar case related to NASA involved the "GFAJ-1" bacteria: there's nothing really special about identifying a arsenic-resistant bacteria, but it's worldwide news to discover a new life-form based on arsenic instead of phosphorus. Therefore a few researches (unconsciously or otherwise) tried really hard to find enough evidence to claim they found it. See further details here and here.

    A related problem is that nobody likes to give bad news to their boss/investors/whatever, especially in large corporations, since this may affect their bonus/promotion/funding/whatever. Therefore people usually minimizes problems when reporting to their boss, that minimizes them even more when reporting it further, and so on.

    In 20 years of experience in IT consulting, I saw quite a few times companies working on project schedules, not to determine the time required to complete the project, but merely to produce a "convincing" document to support a certain previously established deadline. When it happens, just proving it's an unrealistic deadline is frequently not considered a good enough reason to change the schedule. :)
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
Sign In or Register to comment.