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; } } }