package fast

import 

const (
	diyFpKSignificandSize        = 64
	kSignificandSize             = 53
	kUint64MSB            uint64 = 1 << 63

	kSignificandMask = 0x000FFFFFFFFFFFFF
	kHiddenBit       = 0x0010000000000000
	kExponentMask    = 0x7FF0000000000000

	kPhysicalSignificandSize = 52 // Excludes the hidden bit.
	kExponentBias            = 0x3FF + kPhysicalSignificandSize
	kDenormalExponent        = -kExponentBias + 1
)

type double float64

type diyfp struct {
	f uint64
	e int
}

// f =- o.
// The exponents of both numbers must be the same and the significand of this
// must be bigger than the significand of other.
// The result will not be normalized.
func ( *diyfp) ( diyfp) {
	_DCHECK(.e == .e)
	_DCHECK(.f >= .f)
	.f -= .f
}

// Returns f - o
// The exponents of both numbers must be the same and this must be bigger
// than other. The result will not be normalized.
func ( diyfp) ( diyfp) diyfp {
	 := 
	.subtract()
	return 
}

// f *= o
func ( *diyfp) ( diyfp) {
	// Simply "emulates" a 128 bit multiplication.
	// However: the resulting number only contains 64 bits. The least
	// significant 64 bits are only used for rounding the most significant 64
	// bits.
	const  uint64 = 0xFFFFFFFF
	 := .f >> 32
	 := .f & 
	 := .f >> 32
	 := .f & 
	 :=  * 
	 :=  * 
	 :=  * 
	 :=  * 
	 := ( >> 32) + ( & ) + ( & )
	// By adding 1U << 31 to tmp we round the final result.
	// Halfway cases will be round up.
	 += 1 << 31
	 :=  + ( >> 32) + ( >> 32) + ( >> 32)
	.e += .e + 64
	.f = 
}

// Returns f * o
func ( diyfp) ( diyfp) diyfp {
	 := 
	.mul()
	return 
}

func ( *diyfp) () {
	,  := .f, .e
	// This method is mainly called for normalizing boundaries. In general
	// boundaries need to be shifted by 10 bits. We thus optimize for this case.
	const  uint64 = 0x3FF << 54
	for & == 0 {
		 <<= 10
		 -= 10
	}
	for &kUint64MSB == 0 {
		 <<= 1
		--
	}
	.f, .e = , 
}

func normalizeDiyfp( diyfp) diyfp {
	 := 
	._normalize()
	return 
}

// f must be strictly greater than 0.
func ( double) () diyfp {
	,  := .sigExp()

	// The current float could be a denormal.
	for ( & kHiddenBit) == 0 {
		 <<= 1
		--
	}
	// Do the final shifts in one go.
	 <<= diyFpKSignificandSize - kSignificandSize
	 -= diyFpKSignificandSize - kSignificandSize
	return diyfp{, }
}

// Returns the two boundaries of this.
// The bigger boundary (m_plus) is normalized. The lower boundary has the same
// exponent as m_plus.
// Precondition: the value encoded by this Double must be greater than 0.
func ( double) () (,  diyfp) {
	 := .toDiyFp()
	 := .f == kHiddenBit
	 = normalizeDiyfp(diyfp{f: (.f << 1) + 1, e: .e - 1})
	if  && .e != kDenormalExponent {
		// The boundary is closer. Think of v = 1000e10 and v- = 9999e9.
		// Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
		// at a distance of 1e8.
		// The only exception is for the smallest normal: the largest denormal is
		// at the same distance as its successor.
		// Note: denormals have the same exponent as the smallest normals.
		 = diyfp{f: (.f << 2) - 1, e: .e - 2}
	} else {
		 = diyfp{f: (.f << 1) - 1, e: .e - 1}
	}
	.f <<= .e - .e
	.e = .e
	return
}

func ( double) () diyfp {
	,  := .sigExp()
	return diyfp{f: , e: }
}

func ( double) () ( uint64,  int) {
	 := math.Float64bits(float64())
	 =  & kSignificandMask
	if &kExponentMask != 0 { // not denormal
		 += kHiddenBit
		 = int((&kExponentMask)>>kPhysicalSignificandSize) - kExponentBias
	} else {
		 = kDenormalExponent
	}
	return
}