Hi there,
I seem to be having problems multiply two BigDecimal numbers without loss. Can anybody explain to me how to do this, please?

Hi there,

The real problem is that I have got a method in my algorithm, and whenever a BigDecimal number is passed into this method, it produces the right answer in the first iteration of the algorithm, but in the second iteration when another BigDecimal number is passed, it often produced 0E-10. Here is the method:

public BigDecimal sigmoidActivationFunction(BigDecimal sum)
       {
   	  Big_pi test2 = new Big_pi();
         //sum = sum.multiply(new BigDecimal(-1.0));
     	  BigDecimal Set =new BigDecimal("1").add( test2.exp(sum.negate()));
     	  BigDecimal Set1 = new BigDecimal("1").divide(Set,10,RoundingMode.HALF_UP);

   	  return Set1;
     }

and the method "exp" (is used to find the exp of a number) in the class Big_pi that the above method used is as shown below:

import java.math.BigDecimal;

public class Big_pi
{
  BigDecimal epsilon; // based on desired precision
  BigDecimal natural_e;
  BigDecimal pi;
  int prec = 301; // precision in digits
  int bits = 1000; // precision in bits = about 3.32 precision in digits
  public Big_pi() // constructor
  {
    BigDecimal a = new BigDecimal("0.12345678901234567890");
    BigDecimal b = new BigDecimal("0.2345678901234567890");
    BigDecimal c;
    BigDecimal npi;

    // "constants" needed by other functions
    natural_e = naturalE(prec); /* precision */
    epsilon = new BigDecimal("1");
    for(int i=0; i<bits; i++)
    {
      epsilon = epsilon.multiply(new BigDecimal("0.5"));
    }
 }

 public BigDecimal exp_series(BigDecimal x) // abs(x)<=0.5, prec digits
  {                                   // prec digits returned
    BigDecimal fact = new BigDecimal("1"); // factorial
    BigDecimal xp   = new BigDecimal("1"); // power of x
    BigDecimal y    = new BigDecimal("1"); // sum of series on x
    int n;

    n = (2*prec)/3;
    for(int i=1; i<n; i++)
    {
      fact = fact.multiply(new BigDecimal(i));
      fact = fact.setScale(prec,BigDecimal.ROUND_DOWN);
      xp   = xp.multiply(x);
      xp = xp.setScale(prec,BigDecimal.ROUND_DOWN);
      y = y.add(xp.divide(fact, BigDecimal.ROUND_DOWN));
    }
    y = y.setScale(prec,BigDecimal.ROUND_DOWN);
   return y;
  }

  public BigDecimal exp(BigDecimal x)
  {
    BigDecimal y = new BigDecimal("1.0");  // sum of series on xc
    BigDecimal xc;                         // x - j
    BigDecimal ep = natural_e;             // e^j
    BigDecimal j  = new BigDecimal("1");
    BigDecimal one = new BigDecimal("1.0");
    BigDecimal half = new BigDecimal("0.5");
    BigDecimal xp;                         // positive, then invert

    if(x.abs().compareTo(half) <0) return exp_series(x);
    if(x.compareTo(new BigDecimal("0"))>0) // positive
    {
      while(x.compareTo(j.add(one))>0)
      {
		  ep = ep.multiply(natural_e);
        j = j.add(one);
      }
      xc = x.subtract(j);
      y = ep.multiply(exp_series(xc));
      y = y.setScale(prec,BigDecimal.ROUND_DOWN);
      return y;
    }
    else // negative
    {
      xp = x.negate();
      while(xp.compareTo(j.add(one))>0)
      {
		  ep = ep.multiply(natural_e);
        j = j.add(one);
      }
      xc = xp.subtract(j);
      y = ep.multiply(exp_series(xc));
      y = y.setScale(prec,BigDecimal.ROUND_DOWN);
      return (one.add(epsilon)).divide(y, BigDecimal.ROUND_DOWN);
    }
  } // end exp

  public BigDecimal naturalE(int prec_dig)
  {
    BigDecimal sum  = new BigDecimal("1");
    BigDecimal fact = new BigDecimal("1");
    BigDecimal del  = new BigDecimal("1");
    BigDecimal one  = new BigDecimal("1");
    BigDecimal ten  = new BigDecimal("10");
    int prec_bits = (prec_dig*332)/100;

    one = one.setScale(prec_dig,BigDecimal.ROUND_DOWN);
    for(int i=0; i<prec_dig; i++) del = del.multiply(ten);
    for(int i=1; i<prec_bits; i++)
    {
      fact = fact.multiply(new BigDecimal(i));
      fact = fact.setScale(prec_dig,BigDecimal.ROUND_DOWN);
      sum = sum.add(one.divide(fact, BigDecimal.ROUND_DOWN));
      if(del.compareTo(fact) <0) break;
    }
    return sum.setScale(prec_dig,BigDecimal.ROUND_DOWN);
  }


}

for example, in the first iteration, if the value -0.491340681290030168 is passed into the method sigmoidActivationFunction above, it produced the right value: 0.3795777883. In the second iteration of the algorithm, when the value: -136.6261102667 is passed into the sigmoidActivationFunction method, the value 0E-10 is produced which is wrong, it should be 3.17435854...E-60 So i suspected that it might be a precision problem, but i am not sure.

This article has been dead for over six months. Start a new discussion instead.