Python转C代码后数组重复次数统计异常的原因与修复方法
C语言浮点数组连续重复次数统计异常原因及修复方案
问题描述
- 现有Python代码可实现:根据阈值统计数组中元素的连续重复次数(两元素差值≤阈值视为连续重复),输出格式为
[元素值, 重复次数]。输入SenList=[1.1,1.1,1.2,2.4,2.5,2.3,2.4,8.6,8.5,8.9,9.11]、阈值th=0.1时,输出为[1.2, 3, 2.4, 1, 2.5, 1, 2.3, 1, 2.4, 1, 8.5, 2, 8.9, 1, 9.11, 1]。 - 对应的C代码逻辑看似一致,但运行结果异常:
1.100000 2 1.200000 1 2.500000 2 2.300000 1 2.400000 1 8.600000 1 8.500000 1 8.900000 1 9.110000 1。 - 疑问:为何C代码处理浮点数组时统计错误,处理int数组却正常?请给出修复方案。
附原代码
Python代码
import math def dif(x, y, ma1): res = 0 if math.fabs(x - y) <= ma1: res = 1 return res def enc(text, th): coded = [] coded.clear() index = 0 unt = 1 while index <= len(text) - 1: if index == len(text) - 1 or dif(text[index], text[index+1], th) != 1: coded.append(text[index]) coded.append(unt) unt = 1 else: unt += 1 index += 1 return coded SenList = [1.1,1.1,1.2,2.4,2.5,2.3,2.4,8.6,8.5,8.9,9.11] th = 0.1 comm = enc(SenList, th) print(comm)
C代码
#include <stdio.h> #include <math.h> int dif(float x,float y,float sigma1){ int res=0; if(fabsf(x-y) <= sigma1) res=1; return res; } void RL(){ float text [] = {1.1,1.1,1.2,2.4,2.5,2.3,2.4,8.6,8.5,8.9,9.11} ; int n = sizeof(text)/sizeof(text[0]); float th =0.1; float num[30]; int nc = 0; int cou[30]; int nc1= 0; int index=0; int unt=1; while (index < n){ if ( (index == n-1) || (dif(text[index],text[index+1],th)!=1) ) { cou[nc] = unt; nc++; num[nc1] = text[index]; nc1++; unt=1; } else{ unt++; } index++; } for(int i=0; i<nc;i++){ printf(" %3f %d \n ",num[i],cou[i]); } } int main() { RL(); return 0; }
原因分析
- 浮点数精度丢失:C语言的
float类型仅能提供约6-7位有效数字精度,像9.11、2.4这类十进制小数无法被二进制浮点数精确表示,实际存储值与字面量存在微小误差。比如2.4和2.5的差值计算后可能因精度问题略大于0.1,导致判断为不连续;而Python的float是双精度(对应C的double),精度更高,误差更小,判断结果更准确。 - 索引维护冗余:C代码中
num和cou数组分别用nc1和nc维护索引,虽然逻辑上两者同步增长,但冗余的变量容易引发潜在错误,不过这不是本次异常的主因。 - int数组无问题的本质:整数可以被
int类型精确存储,不存在精度误差,差值判断完全准确,因此统计结果正常。
修复方案
核心修复:提升浮点数精度
将C代码中所有float类型替换为double,同时使用fabs()(对应双精度的绝对值函数)替代fabsf(),大幅减少精度误差。
辅助修复:简化索引维护
合并nc和nc1为单个索引变量,避免索引不同步的潜在问题。
修复后的完整C代码
#include <stdio.h> #include <math.h> int dif(double x, double y, double sigma1) { int res = 0; if (fabs(x - y) <= sigma1) res = 1; return res; } void RL() { double text[] = {1.1, 1.1, 1.2, 2.4, 2.5, 2.3, 2.4, 8.6, 8.5, 8.9, 9.11}; int n = sizeof(text) / sizeof(text[0]); double th = 0.1; double num[30]; int cou[30]; int index = 0; int unt = 1; int count = 0; // 统一维护元素和计数的索引 while (index < n) { if (index == n - 1 || dif(text[index], text[index + 1], th) != 1) { cou[count] = unt; num[count] = text[index]; count++; unt = 1; } else { unt++; } index++; } // 按更清晰的格式输出 for (int i = 0; i < count; i++) { printf("%.2f %d\n", num[i], cou[i]); } } int main() { RL(); return 0; }
修复后运行结果将与Python代码一致,准确统计连续重复次数。
内容的提问来源于stack exchange,提问作者lena
相关产品推荐
相关产品推荐

