fdiv2 method

bool fdiv2(
  1. MPData ret,
  2. MPData a,
  3. MPData b,
  4. int prec, [
  5. ParamInteger? _digit,
])

Implementation

bool fdiv2( MPData ret, MPData a, MPData b, int prec, [ParamInteger? _digit] ){
	a = clone( a );
	b = clone( b );

	_digit ??= ParamInteger();

	int P = getPrec( a );

	/*
	 * 被除数の整数部の桁数を求める
	 */
	int l = getLen( a );
	int k = 10;
	int i;
	for( i = 1; i <= digit; i++ ){
		if( a.val(l) < k ){ break; }
		k *= 10;
	}
	_digit.set( ((l - 1) * digit + i) - P );

	if( prec < _digit.val() ){
		prec = _digit.val();
	}

	/*
	 * bb = 1 / b
	 */
	MPData bb = MPData();
	MPData aa = MPData();
	_setLen( aa, 1 ); aa.set( 1, 1 );
	int p = _matchPrec( aa, b );
	k = b.val(0) < 0 ? -1 : 1;
	l = getLen( b );
	for( i = l; i > 0; i-- ){
		if( b.val(i) != 0 ){ break; }
	}
	if( i == 0 ){ return true; }
	if( i != l ){
		p -= (l - i) * digit;
		_setPrec( aa, p );
		_setPrec( b, p );
		_setLen( b, i * k );
	}
	MPData q = MPData();
	MPData r = MPData();
	div( q, aa, b, r );
	p = prec * 2 + 1; // 精度を保つために桁数を増やす
	int t = _fmul( q, p );
	_fmul( r, p );
	if( t > 0 ){
		MPData k = MPData();
		_fcoef( k, t );
		mul( q, q, k );
		mul( r, r, k );
	}
	div( r, r, b );
	if( getLen( a ) == 1 && a.val(1) == 1 ){
		add( ret, q, r );
		if( a.val(0) < 0 ){ ret.set( 0, -ret.val(0) ); }
		_setPrec( ret, p );
		return false;
	} else {
		add( bb, q, r );
		_setPrec( bb, p );
	}

	/*
	 * ret = a * bb
	 */
	mul( ret, a, bb );
	p += P;
	int n = (p - (prec + digit)) ~/ digit;
	if( n > 0 ){
		p -= n * digit;
		_fdiv( ret, n );
	}
	_setPrec( ret, p );

	return false;
}