package utils

import (
	"math"
)

// fastInvSqrt 实现了卡马克的快速平方根倒数算法
func fastInvSqrt(x float32) float32 {
	xhalf := float32(0.5) * x
	i := math.Float32bits(x)           // 将浮点数转换为32位整数
	i = 0x5f3759df - (i >> 1)          // 神奇数字和位操作
	y := math.Float32frombits(i)       // 将整数转换回浮点数
	y = y * (float32(1.5) - xhalf*y*y) // 牛顿迭代一步提高精度
	return y
}

// fastSqrtCarmack 使用卡马克算法计算平方根
func fastSqrtCarmack(x float64) float64 {
	if x == 0 || math.IsNaN(x) || math.IsInf(x, 1) {
		return x
	}
	if x < 0 {
		return math.NaN()
	}

	x32 := float32(x)
	invSqrt := fastInvSqrt(x32)
	return float64(x32) * float64(invSqrt)
}

// fastSqrt 使用快速平方根倒数算法计算平方根
func fastSqrt(x float64) float64 {
	// 处理特殊情况
	if x == 0 || math.IsNaN(x) || math.IsInf(x, 1) {
		return x
	}
	if x < 0 {
		return math.NaN()
	}

	// 转换为float32进行卡马克算法计算
	x32 := float32(x)
	invSqrt := fastInvSqrt(x32)

	// 转回float64并计算平方根
	result := float64(x32) * float64(invSqrt)
	return result
}

// fastSqrtInt 实现了针对整数的快速平方根算法
func fastSqrtInt(n int) int {
	if n < 0 {
		return 0 // 处理负数情况
	}
	if n == 0 || n == 1 {
		return n
	}

	// 使用浮点数版本的快速平方根
	x := float64(n)
	sqrt := fastSqrt(x)
	return int(sqrt + 0.5) // 四舍五入转换为整数
}
