using System;
using System.Collections.Generic;
using System.Linq;
using ET;
namespace Hutool
{
public static class MathUtil
{
///
/// 检查指定位置的位是否为1
///
/// 要检查的整数
/// 要检查的位位置
/// 如果指定位置的位为1,则返回true;否则返回false,注意:index不合法将会返回false
public static bool isBitSet(long value, int index)
{
// 检查指定的位位置是否在合法范围内
//sizeof(int) * 8 的结果就是 long 类型的二进制位数.long占用8字节,即64位
if (index < 0 || index >= sizeof(long) * 8)
{
Log.Error($"value:{value},index:{index},超出索引");
return false;
}
// 使用按位与运算符 & 将指定位置的位与1进行比较
// 如果结果不为0,则表示该位为1,返回true
// 如果结果为0,则表示该位为0,返回false
return (value & (1 << index)) != 0;
}
///
/// 将指定位置的位设置为1
///
/// 待修改的整数
/// 要设置为1的位位置数组
/// 修改后的整数,报错返回默认值,注:bitPositions不合法将返回原始num
public static int SetBitsTo1(int num, int[] bitPositions)
{
// 检查位位置数组是否为空
if (bitPositions == null)
{
Log.Error($"num:{num}, bitPositions is null.");
return num;
}
// 检查位位置是否在合法范围内
int bitCount = sizeof(int) * 8;
foreach (int bitPos in bitPositions)
{
if (bitPos < 0 || bitPos >= bitCount)
{
Log.Error($"num:{num}, bitPositions bitPos:{bitPos} 超出索引");
return num;
}
}
var mask = bitPositions.Aggregate(0, (current, bitPos) => current | 1 << bitPos);
return num | mask;
}
///
/// 32位中设置某一位为1
///
/// 待设置的32位整数
/// 要设置为1的位的位置
/// 设置后的整数,注:bitPos不合法将返回原始num
public static int SetBitsTo1(int num, int bitPos)
{
// 检查位位置是否在合法范围内
if (bitPos < 0 || bitPos >= sizeof(int) * 8)
{
Log.Error($"num:{num}, bitPos:{bitPos} 超出索引.");
return num;
}
// 使用按位或操作符 | 将指定位位置的位设置为1
return num | (1 << bitPos);
}
///
/// 64位中,设置某一位为1
///
/// 待设置的64位整数
/// 要设置为1的位的位置
/// 设置后的值,注:bitPos不合法将返回原始num
public static long SetBitsTo1Long(long num, int bitPos)
{
// 检查位位置是否在合法范围内
if (bitPos < 0 || bitPos >= sizeof(long) * 8)
{
Log.Error($"num:{num}, bitPos:{bitPos} 超出索引");
return num;
}
return num | (1L << bitPos);
}
///
/// 将指定位置的位设置为0
///
/// 待修改的整数
/// 要设置为0的位位置
/// 修改后的整数,注:如果bitPosition不合法将返回原始num
public static int SetBitsTo0(int num, int bitPosition)
{
// 检查位位置是否在合法范围内
int bitCount = sizeof(int) * 8;
if (bitPosition < 0 || bitPosition >= bitCount)
{
Log.Error($"num:{num}, bitPosition: {bitPosition} 超出索引");
return num;
}
// 创建掩码
int mask = 1 << bitPosition;
// 使用掩码将指定位设置为0
return num & ~mask;
}
///
/// 将指定位置的位设置为0
///
/// 待修改的整数
/// 要设置为0的位位置数组
/// 修改后的整数,注:bitPositions存在不合法的位将返回原始num
public static int SetBitsTo0(int num, int[] bitPositions)
{
// 检查位位置数组是否为空
if (bitPositions == null)
{
Log.Error("bitPositions is null.");
return num;
}
// 检查位位置是否在合法范围内
int bitCount = sizeof(int) * 8;
foreach (int bitPos in bitPositions)
{
if (bitPos < 0 || bitPos >= bitCount)
{
Log.Error($"num:{num}, bitPositions bitPos:{bitPos} 超出索引");
return num;
}
}
var mask = bitPositions.Aggregate(0, (current, bitPos) => current | 1 << bitPos);
return num & ~mask;
}
///
/// 统计32位无符号整数中的1位数目
///
/// 要统计的32位无符号整数
/// 1的位数目
public static int CountOnes(int num)
{
var count = 0;
for (int i = 0; i < 32; i++)
{
// 检查 num 的最低位是否为1,如果是则 count 加1
if ((num & 1) == 1)
{
count++;
}
// 将 num 向右移动一位,继续检查下一位
num >>= 1;
}
return count;
}
///
/// 统计64位无符号整数中的1位数目
///
/// 要统计的64位无符号整数
/// 1的位数目
public static int CountOnes2(long num)
{
var count = 0;
for (int i = 0; i < 64; i++)
{
// 检查 num 的最低位是否为1,如果是则 count 加1
if ((num & 1) == 1)
{
count++;
}
// 将 num 向右移动一位,继续检查下一位
num >>= 1;
}
return count;
}
///
/// 获取下一个索引,超出范围就获取0.
///
/// 当前索引
/// 数组长度
/// 返回下一个索引;返回true表示是新的一轮,返回false表示当轮
public static (int, bool) GetArIndex(int curIndex, int arrLength)
{
int nextIndex;
bool curIndexIsMax;
if (curIndex == arrLength - 1)
{
// 当前索引已经是最大索引
nextIndex = 0; // 重置获取索引为 0
curIndexIsMax = true;
}
else
{
// 当前索引不是最大索引
nextIndex = curIndex + 1; // 获取下一个索引
curIndexIsMax = false;
}
return (nextIndex, curIndexIsMax);
}
///
/// 从issueNumbers里匹配下一个issueNumber
///
///
///
///
public static int GetNextIssueNumber(int issueNumber, int[] issueNumbers)
{
// 如果整数数组为空,无法获取下一个期号,返回默认值 0
if (issueNumbers == null || issueNumbers.Length == 0)
{
return 0;
}
// 查找 TeaPartyOpenCfgId 在整数数组中的索引
int index = Array.IndexOf(issueNumbers, issueNumber);
// 如果 TeaPartyOpenCfgId 不在整数数组中或者是整数数组的最后一个元素,则返回整数数组的第一个元素作为下一个期号
if (index == -1 || index == issueNumbers.Length - 1)
{
return issueNumbers[0];
}
// 返回相邻的下一个元素作为下一个期号
return issueNumbers[index + 1];
}
public static int ProgressCalculate(int haveCount, int totalCount)
{
if (haveCount > totalCount)
{
haveCount = totalCount;
}
float rate = haveCount * 100.0f / totalCount;
int result;
if (rate > 0 && rate <= 1)
{
result = 1;
}
else if (rate >= 99 && rate < 100)
{
result = 99;
}
else
{
result = (int)Math.Round(rate);
}
return result;
}
///
/// 假设为[1,2,3,4,5,6] 如果我知道3,然后需要返回上一条数据2. 如果我知道的是1,上面已经没有数据了,就返回0
///
///
///
///
public static int FindPreviousNumber(List list, int target)
{
if (list.Contains(target))
{
int index = list.IndexOf(target);
if (index > 0)
{
return list[index - 1];
}
}
return 0;
}
//遍历数组dropTimesArr,并检查每个元素是否大于或等于appearNum
public static int GetIndex(int[] dropTimesArr, int appearNum)
{
for (int i = 0; i < dropTimesArr.Length; i++)
{
if (dropTimesArr[i] >= appearNum)
{
return i;
}
}
// 如果没有找到满足条件的元素,返回-1
return -1;
}
public static int GetIndex(List dropTimesArr, int appearNum)
{
for (int i = 0; i < dropTimesArr.Count; i++)
{
if (dropTimesArr[i] >= appearNum)
{
return i;
}
}
// 如果没有找到满足条件的元素,返回-1
return -1;
}
}
}