3

I'm doing calculations on High decimal precision BigDecimal objects.

I'm using a third party library that requires the parameter in double. When I try to convert this to double i get the values in exponential format instead of decimals .

BigDecimal 0.000035000000000
Double 3.5E-5
BigDecimal bd; 
BigDecimal(0.0000349999999995631583260546904057264328002929687500);
bd= bd.setScale(15,BigDecimal.ROUND_CEILING);

Log.i("bd","bd "+bd.toPlainString());
Log.i("bd","double"+bd.doubleValue());

I have found various ways of converting this 3.5E-5 value as correct decimal in points but in String format only . Whereas I need the value in double

Able to get without exponential in String object But not in double

  DecimalFormat df = new DecimalFormat("#");
        df.setMaximumFractionDigits(16);
       String test=df.format(bd,doubleValue());
        System.out.println("op2 "+test);
        Double test1=Double.parseDouble(test);
        System.out.println("op2 "+test1);

OUTPUT op2 .000035 op2 3.5E-5

I'm struggling since since days to find a solution as I have no control over 3rd party library that requires the value to be in double

Refferred Links

Format BigDecimal without scientific notation with full precission

Converting exponential value in java to a number format

Conversion from exponential form to decimal in Java

How to resolve a Java Rounding Double issue

Java BigDecimal without E

How to Avoid Scientific Notation in Double?

My question is different then these links, I do not want the double as string without exponential instead I want it in double format only.

EDIT

If the double value passed is in exponential format, the NDK based libary will further do calculations on this object, which will result inmore decimal points and larger Exponential value. So, I want to pass a simple double without E

Community
  • 1
  • 1
Rachita Nanda
  • 4,509
  • 9
  • 42
  • 66
  • I would guess that this is just the printing of the value that causes this. The value is a primitive double. – Scary Wombat Aug 25 '16 at 06:48
  • 1
    @ScaryWombat I checked it, when I debug also, the double object shows value in E format – Rachita Nanda Aug 25 '16 at 06:49
  • my point being if a third party library expects a primitive double as a parameter, then that is exactly what you are giving them – Scary Wombat Aug 25 '16 at 06:53
  • when I pass this current double object the output from the library method is incorrect. The library is NDK based – Rachita Nanda Aug 25 '16 at 06:54
  • 2
    I dont get it. When your 3rd party library wants **double** values; why are worried about **string formatting**? You do bigInteger.doubleValue() and pass that to your 3rd party library. Done. – GhostCat Aug 25 '16 at 06:56
  • @GhostCat Could not say it better myself - thanks – Scary Wombat Aug 25 '16 at 06:57
  • Output streams aren't incorrect. They simple format as they are told to. If you don't like the way your 3rd party formats its values; then see what you can do about that. But don't expect that you can put some magic into **primitive double values** to affect how some code will format then at some point in the future. Simply not possible. – GhostCat Aug 25 '16 at 06:58
  • @GhostCat when I pas s this current double object the output from the library method is incorrect. The library is NDK based. – Rachita Nanda Aug 25 '16 at 06:59
  • @RachitaNanda Again: the only place that matters than is the 3rd party library and their **formatting** of values when writing them as strings somewhere. This has **nothing** to do with BigIntegers or doubles in general. I dont see any other option for you but to figure if you can somehow configure the **formatting** options for the 3rd party library. You know, when A passes B and apple, and B passes the apple to C; and then C decides to slice that apple ... and A doesn't like sliced apples ... well, then A and B are still not the ones who sliced the apple. – GhostCat Aug 25 '16 at 07:17
  • @RachitaNanda: A double is a double is a double. The **format** (exponential or plain) is not how it is **stored**, it is only how it is **presented** by a library. The presentation does not change the double, and the same double can be presented differently (exponential or not), depending of the format output settings you pass to it. In other words, the double has no internal exponential or plain format, it is the same double. Only the conversion to a string can present you with different formats. So just convert the BigDecimal to a double, since that is what the library obviously expects. – Rudy Velthuis Aug 25 '16 at 15:40
  • Thanks all for explaining@RudyVelthuis @GhostCat – Rachita Nanda Aug 26 '16 at 07:31

2 Answers2

6

You seem to be confusing a double, a 64 bit value where different bits have a different meaning, with its string representation.

Let's take a value of 0.015625. Internally, the double is represented as 64 bits (I don't know right now which combination of bits, but that is irrelevant anyway).

But the string representation depends on the format settings of the library you are using. Note that the representations 0.015625 and 1.5625E-2 represent the exact same double value. The double is not stored as a string, it does not contain a . or an E, just a number of bits. The combination of these bits form its real value, and it is the same, no matter how you represent it as a string. If you have a different format setting, the result can just as well be 1.56E-2. This just means that the code that converts the internal bit combination of the double to a string does some rounding.

So, to obtain a double from a BigDecimal, simply use bd.doubleValue(). There is no need to use an intermediate string representation, and it can even be detrimental to do so, because if the string representation performs some rounding, you don't get the best approximation of the value in the BigDecimal.

So again, bd.doubleValue() is the only correct way to do this. This does not return a specific format, it simply returns the double that is closest to the value in the BigDecimal.

And again, do not confuse the double type with how it is represented as a string. These are different things. A double is a double is a double, and that is not stored as a string, exponential or plain or rounded or whatever.

Actually, BigDecimal.toString() and BigDecimal.toPlainString() also return different string representations of the same BigDecimal. AFAIK, there is even a third string conversion function, toEngineeringString(), which gives you yet another string representation of the same BigDecimal. This is similar for double: different output routines with different arguments return different strings for the exact same value.

Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
1

use this: amount=value to be converted to double from string

    double dd = new BigDecimal(amount).doubleValue();
    String val = String.format("%.4f", dd);
    BigDecimal bd = BigDecimal.valueOf(Double.valueOf(val));
    Double d=bd.doubleValue() ;
    DecimalFormat formatter = new DecimalFormat("0.0000");
    System.out.println("doubleValue= " + formatter .format(d));