void ReverseNumber(void){ int x = 0; fprintf(stderr, "开始解答:逆序数字\n"); printf("请输入一个待逆序的整数\n"); scanf("%d", &x); int digits; if ( x > 0) digits = floor(log10(x)) + 1; else if (x < 0) digits = floor(log10(-x)) + 1; else digits = 0; // fprintf(stderr, "digits=%d", digits); int const kDIVIDER = 10; int o = 0; int i = digits; int n = 0; /* Reverse function */ while (i != 0) { n = x % kDIVIDER; x = x / kDIVIDER; o = o + n * power10(i - 1); // fprintf(stderr, "Last Digit=%d, Truncated Value=%d, Output=%d, step=%d\n", n, x, o, i); i --; } printf("%d\n", o); }
int myatoi(const char *str) //将字符str转换为整数 { const char *p = NULL; int neg; //标志位,0代表负数,1代表正数 if (str[0] == '-') //str为负整数,置neg标志位为0 { neg = 0; p = ++str; //将字符串str字符串中的'-'去除,从str的第二位开始转化 } else //否则置neg标志位为1 { neg = 1; p = str; } int i_len = len(p); //调到字符串长度 int i_temp = i_len; int value = 0; int i = 0; for (; i < i_len; i++) //从str[0]开始遍历字符串 { value += (power10(i_temp - 1) * char2i(p[i])); i_temp--; } if (neg == 0) //str为负数 ,将转化后的字符串前 { return 0 - value; } else { return value; } }
//{4,3,2,1} -> 4321 int digstoval(int * digits) { int i; int sum=0; for(i=0; i<4; i++) sum += digits[i] * power10(i); return sum; }
bool to_rational(const exprt &expr, rationalt &rational_value) { if(expr.id()!=ID_constant) return true; const std::string &value=expr.get_string(ID_value); std::string no1, no2; char mode=0; for(std::string::const_iterator it=value.begin(); it!=value.end(); ++it) { const char ch=*it; if(isdigit(ch)) { if(mode==0) no1+=ch; else no2+=ch; } else if(ch=='/' || ch=='.') { if(mode==0) mode=ch; else return true; } else return true; } switch(mode) { case 0: rational_value=string2integer(no1); break; case '.': rational_value=string2integer(no1); rational_value+=rationalt(string2integer(no2))/power10(no2.size()); break; case '/': rational_value=string2integer(no1); rational_value/=string2integer(no2); break; default: return true; } return false; }
bool to_rational(const exprt &expr, rationalt &rational_value) { if(expr.id()!="constant") return true; const std::string &value=expr.get_string("value"); std::string no1, no2; char mode=0; for(unsigned i=0; i<value.size(); i++) { char ch=value[i]; if(isdigit(ch)) { if(mode==0) no1+=ch; else no2+=ch; } else if(ch=='/' || ch=='.') { if(mode==0) mode=ch; else return true; } else return true; } switch(mode) { case 0: rational_value=string2integer(no1); break; case '.': rational_value=string2integer(no1); rational_value+=rationalt(string2integer(no2))/power10(no2.size()); break; case '/': rational_value=string2integer(no1); rational_value/=string2integer(no2); break; default: return true; } return false; }
void number_to_str(float number, char *str,int afterdecimal){ int n = (int)number, f = (int)((number - n) * power10(afterdecimal)), i= 0; if (number < 0) str[i++] = '-'; // changing -ves to +ves if (n < 0) n = -n; if (f < 0) f = -f; str[i++] = n % 10 + '0'; while (n /= 10) str[i++] = n % 10 + '0'; rev(str, number < 0 ? 1 : 0, i - 1); if (afterdecimal) { str[i++] = '.'; str[i++] = f % 10 + '0'; while (f /= 10) str[i++] = f % 10 + '0'; rev(str, i - afterdecimal, i - 1); } str[i] = 0; }
/* * 作用:调整指数部分 * 参数: * n:要处理的ln * inc_power:指数增量 >0 增加指数,把整数部分结尾的0去掉 <0 减少指数,增加整数部分结尾的0 * 返回值: * 成功:ln * 失败:返回NULL */ ln ln_adjustpower(ln n,int inc_power) { int a; int res,carry; int zeronum; cell p; //验证参数 if(ln_checknull(n) !=0) { fprintf(stderr,"[%s %d] %s error,reason: ln_checknull fail\n",__FILE__,__LINE__,__FUNCTION__); return NULL; } //如果n是0,让它随便设置指数,反正都一样 if(ln_cmp_int(n,0)==0) { //设置新的指数 n->power+=inc_power; return n; } if(inc_power==0) //指数不变 return n; if(inc_power<0) //减少指数 { //设置新的指数 n->power+=inc_power; //转正 inc_power*=-1; //先乘上剩余部分的0 a=power10(inc_power%DIGIT_NUM); p=n->lsd; res=0; carry=0; while(1) { res=a*p->num+carry; p->num=res%UNIT; carry=res/UNIT; if(p==n->msd) { if(carry>0) //存在进位 { if(n->lsd->lcell ==n->msd) //节点不够 { if(ln_addcell(n,INIT_SIZE) ==NULL) //分配失败 { fprintf(stderr,"[%s %d] %s error,reason: ln_addcell fail\n",__FILE__,__LINE__,__FUNCTION__); return NULL; } } p->hcell->num=carry; n->msd=p->hcell; } break; } p=p->hcell; } inc_power-=inc_power%DIGIT_NUM; while(inc_power>0) { if(n->lsd->lcell !=n->msd) //还有多余的节点,利用它 { n->lsd=n->lsd->lcell; n->lsd->num=0; inc_power-=DIGIT_NUM; } else //一次性分配剩下的节点 { if(ln_addcell(n,inc_power/DIGIT_NUM)==NULL) { fprintf(stderr,"[%s %d] %s error,reason: ln_addcell fail\n",__FILE__,__LINE__,__FUNCTION__); return NULL; } n->lsd=n->msd->hcell; break; } } } else { //获取结尾0的个数 zeronum=ln_endingzeronum(n); if(zeronum==-1) { fprintf(stderr,"[%s %d] %s error,reason: ln_endingzeronum fail\n",__FILE__,__LINE__,__FUNCTION__); return NULL; } //不能去掉这么多0 if(inc_power>zeronum) { fprintf(stderr,"[%s %d] %s error,reason: inc_power too large (%d)\n",__FILE__,__LINE__,__FUNCTION__,inc_power); return NULL; } //设置新的指数 n->power+=inc_power; //先处理结尾的0节点 p=n->lsd; while(p->num==0 && inc_power>=DIGIT_NUM) { inc_power-=DIGIT_NUM; p=p->hcell; } n->lsd=p; //除以剩下的0 if(inc_power==0) return n; a=power10(inc_power); p=n->msd; res=0; carry=0; while(1) { res=p->num+carry*UNIT; p->num=res/a; carry=res%a; if(p==n->lsd) break; p=p->lcell; } } return n; }
/* * 作用:把ln取精度 * 副作用:把ln前置0和后置0去掉 * 参数: * n:要处理的ln * precision:所需精度(保留的小数位数) * mode:指定截断或者四舍五入 * 返回值: * 成功:返回ln * 失败:NULL */ ln ln_fix(ln n,int precision,divide_mode mode) { int pointnum; int power; cell p; //验证参数 if(ln_checknull(n)!=0) { fprintf(stderr,"[%s %d] %s error,reason: ln_checknull fail\n",__FILE__,__LINE__,__FUNCTION__); return NULL; } //精度参数有误 if(precision<0) { fprintf(stderr,"[%s %d] %s error,reason: precision error\n",__FILE__,__LINE__,__FUNCTION__); return NULL; } //去除前置0 ln_stripleadingzero(n); //去除后置0 ln_adjustpower(n,ln_endingzeronum(n)); //获取最低节点的小数点位数 pointnum=ln_pointnum(n,n->lsd); //大于pointnum,直接返回 if(precision >=pointnum) return n; //只存在一个节点 if(n->lsd==n->msd) { p=n->lsd; power=power10(pointnum-precision); if(mode==trunc_res) //截断 p->num-=p->num%power; else { if(p->num%power>=5*power/10) p->num=(p->num/power+1)*power; else p->num-=p->num%power; } } else { p=n->lsd; while(pointnum>precision) { p=p->hcell; pointnum-=DIGIT_NUM; } if(pointnum==precision) //现在p所指的节点精度就是precision { if(mode==round_res && p->lcell->num>=UNIT/2) //四舍五入 p->num++; } else { p=p->lcell; power=power10(DIGIT_NUM+pointnum-precision); if(mode==trunc_res) //截断 { p->num-=p->num%power; } else { if(p->num%power>=5*power/10) p->num=(p->num/power+1)*power; else p->num-=p->num%power; } } //p后面有效节点被舍去,因此重置为0 if(p!=n->lsd) { do { p=p->lcell; p->num=0; } while(p!=n->lsd); } } //有可能四舍五入导致溢出,需要做调整 p=n->lsd; while(1) { if(p->num>=UNIT) { p->num-=UNIT; if(p==n->msd) { if(ln_addcell(n,INIT_SIZE) !=NULL) { fprintf(stderr,"[%s %d] %s error,reason: ln_addcell fail\n",__FILE__,__LINE__,__FUNCTION__); return NULL; } n->msd=p->hcell; n->msd->num=1; break; } else { p=p->hcell; p->num+=1; } } else break; } return n; }
//double * //ft_numparse(char **s, bool whole) double * ft_numparse(char **s, int whole) { double mant = 0.0; int sign = 1, exsign = 1, p; double expo = 0.0; static double num; char *string = *s; /* See if the number begins with + or -. */ if (*string == '+') { string++; } else if (*string == '-') { string++; sign = -1; } /* We don't want to recognise "P" as 0P, or .P as 0.0P... */ if ((!isdigit(*string) && *string != '.') || ((*string == '.') && !isdigit(string[1]))) return (NULL); /* Now accumulate a number. Note ascii dependencies here... */ while (isdigit(*string)) mant = mant * 10.0 + (*string++ - '0'); /* Now maybe a decimal point. */ if (*string == '.') { string++; p = 1; while (isdigit(*string)) mant += (*string++ - '0') / power10(p++); } /* Now look for the scale factor or the exponent (can't have both). */ switch (*string) { case 'e': case 'E': /* Parse another number. */ string++; if (*string == '+') { exsign = 1; string++; } else if (*string == '-') { exsign = -1; string++; } while (isdigit(*string)) expo = expo * 10.0 + (*string++ - '0'); if (*string == '.') { string++; p = 1; while (isdigit(*string)) expo += (*string++ - '0') / power10(p++); } expo *= exsign; break; case 't': case 'T': expo = 12.0; string++; break; case 'g': case 'G': expo = 9.0; string++; break; case 'k': case 'K': expo = 3.0; string++; break; case 'u': case 'U': expo = -6.0; string++; break; case 'n': case 'N': expo = -9.0; string++; break; case 'p': case 'P': expo = -12.0; string++; break; case 'f': case 'F': expo = -15.0; string++; break; case 'm': case 'M': /* Can be either m, mil, or meg. */ if (string[1] && string[2] && ((string[1] == 'e') || (string[1] == 'E')) && ((string[2] == 'g') || (string[2] == 'G'))) { expo = 6.0; string += 3; } else if (string[1] && string[2] && ((string[1] == 'i') || (string[1] == 'I')) && ((string[2] == 'l') || (string[2] == 'L'))) { expo = -6.0; mant *= 25.4; string += 3; } else { expo = -3.0; string++; } break; } if (whole && *string != '\0') { return (NULL); } else if (ft_strictnumparse && *string && isdigit(string[-1])) { if (*string == '_') while (isalpha(*string) || (*string == '_')) string++; else return (NULL); } else { while (isalpha(*string) || (*string == '_')) string++; } *s = string; num = sign * mant * pow(10.0, expo); if (ft_parsedb) fprintf(cp_err, "numparse: got %e, left = %s\n", num, *s); return (&num); }
void testPower10() { assertIntEqual(power10(0), 1); assertIntEqual(power10(2), 100); assertIntEqual(power10(4), 10000); }