如何在Objective-C中使用小数变量计算百分比平均值
解决百分比平均值计算的类型适配问题
我来帮你搞定这个计算问题,核心bug出在整数除法的截断特性和变量类型选择上,咱们一步步拆解修改:
问题根源分析
你遇到的80/100返回0的问题,是因为Objective-C里整数除以整数会触发整数除法——结果会直接截断小数部分,只保留整数。所以80(int)除以100(int)的结果就是0,而非你预期的0.8。同时用long类型的totalNumber累加整数,完全丢失了小数精度,最终的平均值计算自然不对。
简单高效的解决方案(用double类型)
这个版本适合大多数普通场景,代码简洁且精度足够:
// 计算特定训练的百分比平均值 double totalPercentage = 0.0; int rawPercentageValue; NSUInteger numberOfObjects = [iterationArray count]; for (NSArray *object in iterationArray) { // 获取原始百分比数值(比如80,代表80%) rawPercentageValue = [(NSNumber *)[object objectAtIndex:4] intValue]; // 用100.0(浮点型)触发浮点除法,得到小数形式的百分比(80 -> 0.8) totalPercentage += rawPercentageValue / 100.0; } // 计算平均小数百分比,再转回百分比数值 double averageDecimal = totalPercentage / numberOfObjects; // 转成long类型:这里用lround做四舍五入,若要直接截断用(long)(averageDecimal * 100)即可 long exercisePercentage = lround(averageDecimal * 100); return exercisePercentage;
关键改动点:
- 把累加变量
totalNumber改成double类型,保留小数精度; - 用
100.0而非100,强制触发浮点除法,避免整数截断; - 最后用
lround()做四舍五入后转成long,符合你返回long类型的需求; - 用
NSUInteger存储数组count,更符合Objective-C的类型规范(数组count是无符号整数)。
高精度场景解决方案(用NSDecimalNumber)
如果你的计算对精度要求极高(比如金融、专业统计场景),可以用NSDecimalNumber避免浮点运算的精度误差:
// 用NSDecimalNumber实现高精度百分比平均值计算 NSDecimalNumber *totalDecimal = [NSDecimalNumber zero]; NSUInteger numberOfObjects = [iterationArray count]; NSDecimalNumber *hundred = [NSDecimalNumber decimalNumberWithString:@"100"]; for (NSArray *object in iterationArray) { NSNumber *rawNumber = [object objectAtIndex:4]; // 把NSNumber转成NSDecimalNumber,保留高精度 NSDecimalNumber *rawDecimal = [NSDecimalNumber decimalNumberWithDecimal:[rawNumber decimalValue]]; // 转换成小数形式的百分比 NSDecimalNumber *percentageDecimal = [rawDecimal decimalNumberByDividingBy:hundred]; // 累加高精度小数 totalDecimal = [totalDecimal decimalNumberByAdding:percentageDecimal]; } // 计算高精度平均值 NSDecimalNumber *averageDecimal = [totalDecimal decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithUnsignedInteger:numberOfObjects]]; // 转回百分比并转成long类型 NSDecimalNumber *averagePercentage = [averageDecimal decimalNumberByMultiplyingBy:hundred]; long exercisePercentage = [averagePercentage longValue]; return exercisePercentage;
这个版本完全基于十进制运算,不会出现浮点运算的精度丢失问题,适合对精度敏感的场景。
内容的提问来源于stack exchange,提问作者Niall Kiddle
相关产品推荐
相关产品推荐

