// Copyright (c) 2016 The mathutil Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package mathutil // import "modernc.org/mathutil"

import (
	

	
)

type float struct {
	n           *big.Int
	fracBits    int
	maxFracBits int
}

func ( *big.Int, ,  int) float {
	 := float{n: , fracBits: , maxFracBits: }
	.normalize()
	return 
}

func ( *float) () {
	 := .n.BitLen()
	if  == 0 {
		return
	}

	if  := .fracBits - .maxFracBits;  > 0 {
		 := .n.Bit( - 1)
		.n.Rsh(.n, uint())
		if  != 0 {
			.n.Add(.n, _1)
		}
		.fracBits -= 
	}

	var  int
	for ; .fracBits > 0 &&  <= .fracBits && .n.Bit() == 0; ++ {
		.fracBits--
	}

	if  != 0 {
		.n.Rsh(.n, uint())
	}
}

func ( *float) () bool { return .fracBits == 0 && .n.BitLen() == 1 }
func ( *float) () bool { return .n.BitLen() > .fracBits+1 }

func ( *float) () {
	.fracBits++
	.normalize()
}

func ( *float) () {
	.n = bigfft.Mul(.n, .n)
	.fracBits *= 2
	.normalize()
}

// BinaryLog computes the binary logarithm of n. The result consists of a
// characteristic and a mantissa having precision mantissaBits. The value of
// the binary logarithm is
//
//	characteristic + mantissa*(2^-mantissaBits)
//
// BinaryLog panics for n <= 0 or mantissaBits < 0.
func ( *big.Int,  int) ( int,  *big.Int) {
	if .Sign() <= 0 ||  < 0 {
		panic("invalid argument of BinaryLog")
	}

	 = .BitLen() - 1
	 = big.NewInt(0)
	 := newFloat(, , )
	for ;  != 0 && !.eq1(); -- {
		.sqr()
		.Lsh(, 1)
		if .ge2() {
			.SetBit(, 0, 1)
			.div2()
		}
	}
	return , 
}