Comparing Numbers

LiveCode uses binary numbers rather than decimal numbers for its internal calculations (for reasons of speed), the internal representation of a number is sometimes slightly off the correct number.

This lesson shows how to test whether two numbers are approximately equal.

Creating the UI

Creating the UI

The UI for this lesson consists of 3 label fields, 3 entry fields and a button.

The three fields are called "firstNumber", "tolerance" and "secondNumber".

Numbers in LiveCode

Since LiveCode uses binary numbers rather than decimal numbers for its internal calculations (for reasons of speed), the internal representation of a number is sometimes slightly off the correct number. This is because it's not possible to write a decimal fraction such as 0.1 exactly as a binary number: there will always be some rounding error, and this error accumulates as mathematical operations are done on the number.

For example, 10^-1 is equal to 0.1, but is calculated (to eighteen decimal places) as 0.100000000000000006. In some cases of repeated mathematical operations, this small error may accumulate to the point where it affects the final result. Setting the numberFormat property to specify many decimal places after the decimal point may also produce unexpected results in a statement that tests for an exact number. In such cases, the "approxEqual" function provides a way of testing whether numbers are close together.

The approxEqual function

We are going to write a function to check whether the two numbers are approximately equal, the handler finds the difference between them using the abs function, and checks whether the difference is less than the tolerance. If so, it returns true and if not it returns false.

The function takes three parameters, the two numbers being compared, and the amount they're allowed to differ before being considered unequal. You'll notice that you can call the function with just two parameters (the two numbers). It's possible to do this because the first line of the function handler checks to see whether there's a third parameter. If not, the handler assigns the value of 1 to the tolerance. In other words, if you don't specify a tolerance when you use the function, it assumes you want to check whether the numbers are within 1 of each other.

You can use this method with any handler to assign a default value to one or more of the parameters. Just check whether the parameter is empty. If it is, then no value has been passed, and you set the default value by simply putting the desired default into the parameter.

The approxEquals Code

Add the approxEqual function to the Card Script.

function approxEqual pFirstNumber,pSecondNumber,pTolerance
   if pTolerance is empty then 
      ## default
      put 1 into pTolerance 
   end if
   
   if abs(pFirstNumber - pSecondNumber) < pTolerance then
      ## the numbers are within tolerance
      return true
   else 
      ## not close enough
      return false
   end if
end approxEqual 

The Compare button code

Add this handler function to the "Compare" button script.

on mouseUp
  if approxEqual(field "firstNumber", field "secondNumber", field "tolerance") then
    answer "Yes:" && field "firstNumber" && "is within" && field "tolerance" && "of" && field "secondNumber" & "."
  else
    answer "No:" && field "firstNumber" && "is not within" && field "tolerance" && "of" && field "secondNumber" & "."
  end if
end mouseUp

Testing - true

Testing - true

Testing - false

Testing - false

0 Comments

Add your comment

E-Mail me when someone replies to this comment