Solved

# how to test for double values being being equal

Posted on 2008-11-13
1,165 Views
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;

}
``````
0
Question by:RichardKline

LVL 15

Expert Comment

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

LVL 24

Expert Comment

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

LVL 1

Author Comment

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

LVL 24

Assisted Solution

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

LVL 11

Expert Comment

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

LVL 1

Author Comment

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

LVL 11

Expert Comment

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

LVL 1

Author Comment

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

}

}

}
``````
0

LVL 11

Accepted Solution

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

LVL 1

Author Comment

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

### Suggested Solutions

commonTwo  challenge 63 70
bunnyEars2 challenge 6 48
What is JNDI datasource in spring 1 21
firstChar challenge 13 60
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input: