Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1200
  • Last Modified:

how to test for double values being being equal

Class Assignment:
As part of a class assignment, I need to count the number of significant digits in a double value without using strings.

The attached code does that but runs into trouble due to the built-in problem of checking for equality in double values.   The Double.compare function  at tne end of the loop just isn't reliable.  see line labeled PROBLEM

Any thoughts on a better way to check for double value equality?

Thank you.
private int numberSignificantDigits(double thisNumber) {
        // result contains the number of significant digits 
        //      (right of decimal)
        // start with -1 as initial value as the loop will always 
        //      run  at least once.
        int result = -1;
        double temp = thisNumber;
        long iPart;
        double fPart;
        
        // repeat look until fractional part of value being 
        //      evaluated <> 0
        do {
            //ipart contains whole number part of double value
            iPart = (long) temp;
            //fpart contains fractional part of double value
            fPart = temp - iPart;
            
            // prepare for next loop by incrementing counter and 
            // mutiplying test value by 10
            result ++;
            temp *= 10;
        }
        // PROBLEM ON NEXT LINE.   How to test for fpart = 0
        while (Double.compare(fPart, 0) != 0);
        return result;
    }

Open in new window

0
RichardKline
Asked:
RichardKline
  • 4
  • 3
  • 2
  • +1
2 Solutions
 
quincydudeCommented:
Hi, you can make them into Double object and use compare method.

see
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Double.html#compare(double, double)
0
 
sciuriwareCommented:
You can NEVER compare float and double values, unless those are copied.

The compare method is unreliable.
All you can do us compare ordinary doubles, when one of them is growing:

double probe = 0.00000000000001; // or such
int counter = 0;
double amount;  // to be tested.

while(amount > probe)
{
     ++ counter;
     probe *= 10.0;
}

Just an example of what you can do.

;JOOP!
0
 
RichardKlineAuthor Commented:
Thank you for the responses.
quincydude, I was not able to get the hyperlink to work and could not read the reference.

sciuriware, the loop also breaks down while using your suggestion (albeit not as quickly!).  

It does appear that my original plan just won't work reliably.

Is there a better way to count the number of significant digits without using String and not hitting the double value compare problem?

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
sciuriwareCommented:
Tip: you can determine the # of significant digits by adding a very small value
and then comparing:

double a = 3.47848278289888;
double b = a + 0.0000000000000000001;

if(a == b)
{
// then the small value could not be added and was NOT significant.


Now you can multiply the small value by 10 repeatedly.
When a != b you know how many zero's there were in the small value,
that is the number of significant digits in a.

;JOOP!
0
 
spoxoxCommented:
There's a problem with the multiplication approach in the original post. 0.5000 has 4 significant digits, but multiplying by 0 will short circuit the calculation.

Sciuriware's solution is good...but I'd do it the other way around! Start with double b = 0.1, and count how many times you have to divide it by 10 until b+a = a.
0
 
RichardKlineAuthor Commented:
I'm sorry.  I'm not getting this.   I'm unsure what "small value" indicates.   Using the following code, both the entered values of 3 and 3.47848278289888 cause "true" to be displayed     Perhaps my question is phrased wrongly.   Assuming the nunmber "3.47848278289888", I need a way to count the number of digits to the right of the decimal point.

Thanks!

public class test {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        double a = scan.nextDouble();
       
        double b = a + 0.0000000000000000001;
        if (a==b)
            System.out.println("true");
        else
            System.out.println("false");
    }
}
0
 
spoxoxCommented:
Two problems:

1) You've omitted the loop that changes the small number value.
2) Numbers too small appear as 0 to the computer. This is why the approach I outlined (in 22965752) is better.
0
 
RichardKlineAuthor Commented:
spoxox and sciuriware:  I feel so slow.   The concept sounds simple but I just can't get my head through its application.   I've been doing database dvelopment for the past x number of years.  Some results of DOUBLE arithmatic computations are driving me even me more bonkers!

It is a lot to ask but would you take a look at the attached code snippet and show me specifically what to change to make it work?  

Thank you.
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
 
import java.util.Scanner;
public class test {
 
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        double a;
        long iPart;
        double thisNumber;
        String trashIt;
 
        System.out.print("-->");
        thisNumber = scan.nextDouble();
        trashIt = scan.nextLine();  // gets rid of trailing carriage return
        System.out.println();
        
 
        while (thisNumber != 0) {
            iPart = (long) thisNumber;
            
            // PROBLEM -- this action initiates JAVA double problem
            a = (thisNumber - iPart);
            
            
            System.out.println("iPart = " + iPart);
            System.out.println("a = " + a);
            
            // PROBLEM:  the problem is "me"  I don't get it.
            int counter = 0;
            if (a != 0) {
                double b = 0.1;
                while (b + a != a) {
                    System.out.println(a + "\t" + b);
                    ++counter;
                    b /= 10;
                }
            }
 
            System.out.println(counter);
            System.out.print("-->");
            thisNumber = scan.nextDouble();
            System.out.println();
            trashIt = scan.nextLine();  // gets rid of trailing carriage return
        }
    }
}

Open in new window

0
 
spoxoxCommented:
You've got what I was talking about there.

I guess the question is ...what answer is expected for a number like 0.5? The computer's internal representation of the number assigns several bits to the mantissa. This means it will be stored as approximately 0.5000000000000001 (or so).

Your original approach (when done correcly; more on that shortly) will tell you that 0.5000 has one significant digit. This is not strictly correct (see University of Guelph Physics dept notes).

Usually, the computer will be using about 16 (decimal) digits to represent the mantissa - even when they're mostly 0.

If your original approach is needed for this assignment, then here's what you need to do to fix it.

1: Initialize your counter to 0, not -1. (Presumably, this is an artifact of an earlier attempt.)
2: Alter the loop to do this:
while (mantissa > 0)
....increment counter
....thisNumber *= 10


I am reluctant to give you the code, as it is a learning assignment. The pseudocode above should be a big hint, though.
Part II of big hint: readability & ease of coding might be increased if "mantissa" is a subroutine/method.
0
 
RichardKlineAuthor Commented:
Thank you both for your help!
I've got it now.

The actual assignment  is to emulate the Windows Calc applicaton (scientific mode for bonus points).  The Physics degree of accuracy would actually be incorrect for this purpose.  (Accountant eyes tend to glaze over not long past F=ma)

0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 4
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now