Switch语句跳过匹配分支进入default的问题求助
问题根源与解决方案
核心问题:浮点数精度误差
你遇到的偶发匹配失败,本质是单精度浮点数(float)的精度缺陷。像0.1f、0.01f这类十进制小数,在二进制中是无限循环的,存储时会被截断,导致实际值和你写的字面量存在微小偏差。比如累加后code的实际值可能是1.1110001f或1.1109999f,而非你预期的1.111f,直接用switch精确匹配就会跳去default。
你之前转string没解决,是因为转string时输出的是四舍五入后的结果(比如显示1.111),但内存里的float仍保留误差,无法通过字符串匹配修正底层精度问题;直接用if-else比较float也是同样的精确匹配逻辑,自然无效。
最优解决方案:用整数替代float
彻底规避精度问题,把方向权重改成整数,确保每个组合的code都是精确值:
修改后的代码
private void NodeEnumeration() { // 遍历_mapArray中所有节点 for(int i = 0; i < _mapSize; i++) { for(int e = 0; e < _mapSize; e++) { // 只处理非0节点 if(_mapArray[i, e] != 0) { int code = 0; // 左节点判断 if(e != 0) { _surroundingNodesPositions[0].x = e - 1; _surroundingNodesPositions[0].y = i; if(_mapArray[(int)_surroundingNodesPositions[0].y, (int)_surroundingNodesPositions[0].x] > 0) { code += 1000; } } // 上节点判断 if(i != 0) { _surroundingNodesPositions[1].x = e; _surroundingNodesPositions[1].y = i - 1; if(_mapArray[(int)_surroundingNodesPositions[1].y, (int)_surroundingNodesPositions[1].x] > 0) { code += 100; } } // 右节点判断 if(e != _mapSize - 1) { _surroundingNodesPositions[2].x = e + 1; _surroundingNodesPositions[2].y = i; if(_mapArray[(int)_surroundingNodesPositions[2].y, (int)_surroundingNodesPositions[2].x] > 0) { code += 10; } } // 下节点判断 if(i != _mapSize - 1) { _surroundingNodesPositions[3].x = e; _surroundingNodesPositions[3].y = i + 1; if(_mapArray[(int)_surroundingNodesPositions[3].y, (int)_surroundingNodesPositions[3].x] > 0) { code += 1; } } AssignValue(i, e, code); } } } } private void AssignValue(int i, int e, int code) { switch(code) { case 1111: _mapArray[i, e] = 1; break; case 1110: _mapArray[i, e] = 2; break; case 1101: _mapArray[i, e] = 3; break; case 1100: _mapArray[i, e] = 4; break; case 1011: _mapArray[i, e] = 5; break; case 1010: _mapArray[i, e] = 6; break; case 1001: _mapArray[i, e] = 7; break; case 1000: _mapArray[i, e] = 8; break; case 111: _mapArray[i, e] = 9; break; case 110: _mapArray[i, e] = 10; break; case 101: _mapArray[i, e] = 11; break; case 100: _mapArray[i, e] = 12; break; case 11: _mapArray[i, e] = 13; break; case 10: _mapArray[i, e] = 14; break; case 1: _mapArray[i, e] = 15; break; case 0: _mapArray[i, e] = 16; break; default: Debug.LogError("MapGenerator::NodeEnumeration()::AssignValue() no value can be assigned | code: " + code); Debug.Log("height: " + i + " width: " + e); break; } }
备选方案:浮点数近似比较(不推荐)
如果一定要保留float类型,可通过判断值的误差范围来匹配,而非精确相等:
private void AssignValue(int i, int e, float code) { const float tolerance = 1e-6f; // 设定极小误差范围 if (Mathf.Abs(code - 1.111f) < tolerance) _mapArray[i, e] = 1; else if (Mathf.Abs(code - 1.110f) < tolerance) _mapArray[i, e] = 2; // 其他case以此类推 else if (Mathf.Abs(code - 0.000f) < tolerance) _mapArray[i, e] = 16; else { Debug.LogError("MapGenerator::NodeEnumeration()::AssignValue() no value can be assigned | code: " + code); Debug.Log("height: " + i + " width: " + e); } }
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

