Visual prolog 7.3 is generating the wrong result for adding two values..

Discussions related to Visual Prolog
User avatar
George
VIP Member
Posts: 313
Joined: 19 Sep 2011 8:54

Visual prolog 7.3 is generating the wrong result for adding two values..

Unread post by George » 25 Oct 2012 10:01

Hi..

Hi,

When we add two real number, The visual prolog 7.3 tool is producing the wrong result.. This is the serious issue in my current project.. Kindly give me way to resolve this issue.

Please find the below examples,

ex:
Input1 = 4777.61
Input2 = 2009.10

Result = Input1 + Input2.

Expected Result is

Result = 6786.71

Tool given result is

Result = 6786.709999999999
Code:

Code: Select all

class predicates     addTwoNo : (real, real) -> real Result. clauses         addTwoNo(Input1, Input2) = Result:-                 Result = Input1 + Input2,                 !.   clauses     run():-         Result = addTwoNo(4777.61, 2009.10),         vpiCommonDialogs::note(tostring(Result))         ...
Kindly help me to resolve this issue as soon as possible.
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282

Randy
Posts: 17
Joined: 17 Nov 2006 13:23

Real Numbers

Unread post by Randy » 25 Oct 2012 10:53

George,

Hello. I don't know if this will help you, but I have a couple of thoughts I thought I would share. To begin with, I searched the Forum a little and noticed you asked a similar question a while back. See the link that follows:

http://discuss.visual-prolog.com/viewto ... mat+output

Also, I've found that dealing with Real Numbers can be challenging in several ways. One has to do with in the Real World Real Numbers have 4 infinite boundaries (Computers have fixed boundaries): Positive/Negative as well as on both sides of the decimal point. It also gets fuzzy sometimes when trying to convert numbers between systems too like a conventional Program language and say a Database System that doesn't usually use it; but both like to represent Real Numbers in some fashion. The problem you seem to be dealing with is how it gets formatted on the output. I would suggest maybe forcing the representation to integers on the input, do the Arithmetic, then format the output to represent the Real number you're interested in for the output; of course this is dependent on the resolution you want as well - your example assumed only 2 decimal positions to the right of the decimal point. You can also play around with the given Formating utilities or creat your own.

Best of Luck,
Randy

User avatar
George
VIP Member
Posts: 313
Joined: 19 Sep 2011 8:54

Unread post by George » 25 Oct 2012 15:49

Randy,

Thanks for your help... But, you have understood my problem wrongly..

I didn't ask the similar question that is asked eariler. My question with the eariler post was the format predicate issue.

But the current issue is with the prolog 7.3 tool issue.. when i add two real number, the tool is giving the wrong output.

To reproduce this issue, please use the value i gave on the previous post.. and use the code i posted.. and run in your tool, you will see the Result value as 4777.61 + 2009.10 = "6786.709999999999".

But take calculator on your pc and calculate the input i posted on the earlier post, you will get the value of 4777.61 + 2009.10 = "6786.71"..

when i add two real number, why i'm getting the wrong output in our tool..


Kindly advice me..
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282

Paul Cerkez
VIP Member
Posts: 202
Joined: 6 Mar 2000 0:01

Unread post by Paul Cerkez » 25 Oct 2012 16:12

George,
I think Thomas' explanation in the previous post explained the reason for what you are seeing. I have seen this in a number of development environments where the precision is not specified.

what I do, is if I know I need X digit precision in the result, I multiple the result of the operation by 10^X, round the value, the divide by 10^X.

this trick has not failed me yet.

just out of curiosity, do you get a different result when you add 4777.61 + 2009.1 ?
AI Rules!
P.

User avatar
George
VIP Member
Posts: 313
Joined: 19 Sep 2011 8:54

Unread post by George » 25 Oct 2012 20:23

Paul Cerkez,

I don't have any restriction to make the precision. I'll take the value as it is.

How come sort out this issue..

I know, this will be solved if we do a rounding with precision 2. But, that's not the correct solution for this..


Is this is PDC bug.???
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282

Harrison Pratt
VIP Member
Posts: 283
Joined: 5 Nov 2000 0:01

Unread post by Harrison Pratt » 25 Oct 2012 22:31

George,

I think you have been seduced by the legacy VIP 5.2 application's behavior, which outputs the result you expect in the desired "apparent" precision when testing it in the File | New (F7) mode.

VIP 7.x encourages you to take responsibility for the precision of your floating point output, which is a very good habit. For example, one may get unexpected results for an expression such as:

Code: Select all

RealVar1 = RealVar2,
Floating point numbers are approximations that may be displayed in ways that belie that imprecison. So, to test for equality of two floating point (real) numbers you need to specify the imprecision and test the difference between the numbers against the precision limit you specify. For example,

Code: Select all

%-- Test for equality of two real variables (VIP 5.2 syntax): RealVar1 - Realvar2 = Delta, AllowableImprecision = 0.001, AbsDelta = abs(Delta), AbsDelta <= AllowableImprecision,
It's not a PDC bug, it the nature of the representation of floating point numbers. Paul and Randy have given very good suggestions and comments -- I hope this addition to their comments helps.

User avatar
George
VIP Member
Posts: 313
Joined: 19 Sep 2011 8:54

Unread post by George » 26 Oct 2012 6:19

If this is not a bug from PDC..

In our 7.x tool, The addition of two values 4777.61 + 2009.1 = 6786.709999999999.. right,.???

If we add those two number manually 4777.61 + 2009.1 = 6786.71 is the output.

please use the below code and see the results,

Code: Select all

class predicates     addTwoNo : (real, real) -> real Result. clauses    addTwoNo(Input1, Input2) = Result:-       Result = Input1 + Input2,       !.   clauses     run():-        Result = addTwoNo(4777.61, 2009.10),        vpiCommonDialogs::note(tostring(Result)
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282

User avatar
Thomas Linder Puls
VIP Member
Posts: 1622
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 26 Oct 2012 13:11

Which version are you using (my Vip7.3 behaves differently)?

Anyways, the following program shows the problem:

Code: Select all

class main predicates     run : (). end class main   implement main     open core   clauses     run():-         addTwoNo(4777.61, 2009.10),         t(6786.71).   class predicates     addTwoNo : (real, real). clauses     addTwoNo(Input1, Input2):-         Result = Input1 + Input2,         t(Input1),         t(Input2),         t(Result).   class predicates     t : (real). clauses     t(A) :-         stdio::writef("%\t%4.20f\n", A, A). end implement main   goal     console::init(),     mainExe::run(main::run).
The program produce this result in Vip7.3 (and also in Vip7.4 (next release)):

<pre>4777.61 4777.60999999999970000000
2009.1 2009.09999999999990000000
6786.71 6786.70999999999910000000
6786.71 6786.71000000000000000000</pre>

Recall from my other mail that all reals cannot be represented, so any real may be represented by a near by number.

The result above shows that 6786.71 have a representation that is so close that it prints back in as itself (last line) even with many digits.

But the two other numbers apparently don't have a close representative. Furthermore, both of them are represented by smaller numbers than the original. So the sum will be too small (as seen in the third line).

If you have a real R then it will be represented by some real R' these two numbers are not always the same, the representation in the computer may introduce a little error e: R' = R + e.

When you add two numbers you will also add the errors, depending on their sign the overall error may thus increase or decrease. Furthermore, the addition may it self introduce additional error because the real result may use more bits than available.

We do not consider any of that as bugs, because it is a completely natural consequence of usingthe real representation that we do (which happens to be the one that the computer naturally use and efficiently supports).

So your program will have to deal with the fact that reals are not precise.
Regards Thomas Linder Puls
PDC

dominique f pannier
VIP Member
Posts: 98
Joined: 23 Sep 2002 23:01

Unread post by dominique f pannier » 26 Oct 2012 13:11

Hi,
I understand Harrison's reasons, but it seems there is finally a problem. The next program :

Code: Select all

run() :-         console::init(),         Result1 = addTwoNo(4777.61, 2009.1),         Result2 = addTwoNo(3510.61, 3512.1),         Result3 = addTwoNo(5510.61, 3512.1), console::writef("R = %\n", Result2).   class predicates     addTwoNo : (real, real) -> real Result. clauses    addTwoNo(Input1, Input2) = Result:-       Result = Input1 + Input2,       !.
displays three outputs with two decimal digits.
But if we trace, the displayed results are :

Result1 = 6786.709999999999
Result2 = 7022.71
Result3 = 9022.709999999999

Then, either there is problem when the number is displayed, or if not why does the Result2 give the right number and Result1 and Result3 give only approached numbers, during tracing operation ?
Regards
Dominique Pannier

dominique f pannier
VIP Member
Posts: 98
Joined: 23 Sep 2002 23:01

Unread post by dominique f pannier » 26 Oct 2012 13:30

Hi,
If I've right understood Thomas'explanations, for Result2 the additionned errors gives the right number.
Regards
Dominique Pannier

User avatar
George
VIP Member
Posts: 313
Joined: 19 Sep 2011 8:54

Unread post by George » 29 Oct 2012 8:40

Which version are you using (my Vip7.3 behaves differently)?
I'm using Visual prolog 7.3

We do not consider any of that as bugs, because it is a completely natural consequence of using the real representation that we do (which happens to be the one that the computer naturally use and efficiently supports).

So your program will have to deal with the fact that reals are not precise.
If the real number is not precise, then that will be the bug right..??

If we look other tools like, .net, java.. they give the exact value know.. any difference b/w there behavior and our tools for handling the real number..?


we also, expect the same result know..


Kindly advice.. :(
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282

User avatar
George
VIP Member
Posts: 313
Joined: 19 Sep 2011 8:54

Unread post by George » 29 Oct 2012 8:56

Additionally, see the result of doing the equality check with the result that we get,

Code: Select all

class predicates     addTwoNo : (real, real) -> real Result determ. clauses         addTwoNo(Input1, Input2) = Result:-                 Result = Input1 + Input2,         t(Result).   class predicates     t : (real) determ. clauses     t(A) :-         6786.71 = A,         X = format("%\t%4.20f\n", A, A),         vpiCommonDialogs::note(X).   run():-         Result = addTwoNo(4777.61, 2009.10).  
Even though both the value is same, that will fail the predicate because of the real value is not correct..
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282

User avatar
George
VIP Member
Posts: 313
Joined: 19 Sep 2011 8:54

Unread post by George » 29 Oct 2012 9:49

If we do a code as below they works well,

Code: Select all

class predicates     addTwoNo : (real, real) -> real Result determ. clauses         addTwoNo(Input1, Input2) = Result:-                 Result = Input1 + Input2,         t(Result).   class predicates     t : (real) determ. clauses     t(A) :-         NewResult = format("%", A),         "6786.71" = NewResult,         vpiCommonDialogs::note("reached").
But doing format for all the real number arithmetic operation is not the good coding practice right.??
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282

User avatar
Thomas Linder Puls
VIP Member
Posts: 1622
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 29 Oct 2012 10:43

It seems that my Vip7.3 (build 7302) must be slightly different from yours, because mine write other values.

However, the difference is only in the writing; the precision problem is present, exactly as it also is in C, C++, Java, .net, and any other language that use a fixed size representation for reals.

Dealing with reals is difficult. Consider this little program (it takes a while to run):

Code: Select all

clauses     run():-         N = 100000000,         O = 0,         S1 = varM::new(O),         foreach A = convert(real, std::fromTo(1, N)) do             S1:value := S1:value+1/(A*A)         end foreach,         S1:value := S1:value - O,         S2 = varM::new(0),         foreach B = convert(real, std::downTo(N, 1)) do             S2:value := S2:value+1/(B*B)         end foreach,        stdio::writef("S1 = %\nS2 = %\nDiff = %\n", S1:value, S2:value, S2:value- S1:value).
Each loop calculates the exact same sum of numbers, the first loop starts with the large numbers and the second starts with the small numers. You will notice that the one that starts with the small numbers reach a higher result than the other one. If you set O large number, things will be even worse even though the result should still be the same.

The problem is that when adding a number to a much large number, you will lose precision.

When checking for equality you will have to allow a little difference (normally called EPSILON in Numerical Analysis).

See also Floating point: Accuracy problems in Wikipedia.
Regards Thomas Linder Puls
PDC

User avatar
Thomas Linder Puls
VIP Member
Posts: 1622
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 29 Oct 2012 10:47

I have not read it (only glanced at it), but appears relevant Comparing floating point numbers.
Regards Thomas Linder Puls
PDC

Post Reply