今天看过《程序员面试宝典》第12章后,发现了一个很严重的错误,在page 147
面试例题:Write a program that convert an octet number to a decimal number(写一个八进制转化成十进制的程序)
原书给的程序是:
unsigned int oct2dec(unsigned int oct)
{
//可以通过加入一个正则表达式确定是否是八进制数,即不包含非法字符
return oct/10*8+oct%10;
}
int main()
{
unsigned int oct=0;
unsigned int dec=0;
cout<<"Please input a octet number(Besure the number you input is begin with a '0'):"<<'/n';
cin>>oct;
dec=oct2dec(oct);
cout<<dec<<endl;
return 0;
}
经本人在VC下调试,运行结果如上图,书中给的这个程序只能将 2位之内的八进制数转化为十进制数
分析下函数oct2dec 它直接返回oct/10*8+oct%10,如果oct是个0到7之间的八进制数,假设oct==4,
代入公式中得4/10*8+4%10=0+4=4,结果正确,因为十进制数4就等同于八进制数4。
如果oct是个10到77之间的八进制数,再假设oct==10或14,代入公式中得10/10*8+10%10=8+0=8, 14/10*8+14%10=8+4=12,结果正确,因为十进制数8就等同于八进制数10,十进制数12就等同于八进制数14。
通过分析可见2位之内的八进制数在函数oct2dec的转化下,能变成十进制数的形式,但是
如果将oct设置为3位八进制数,如:oct = 100 或200 代入公式100%10*8+100%10=80+0=80,200%10*8+200%10=
160+0=160,而实际上八进制100转换成十进制数为 64 ,八进制数200转化成十进制数为128
可见此公式在3位八进制数下就不能正确将其转化为十进制形式
书中给的程序不全面,有局限性
正确的程序应为:
unsigned int power(unsigned int k,unsigned int n)
//计算k的n次方
{
unsigned int result=1;
while(n--)
result=result * k;//累乘
return result;
}
unsigned int oct2dec(unsigned int oct)
{//此函数用来将oct转化成dec
unsigned int result=0;
unsigned int i=0;
while(oct/10)
{
result+=(oct%10)*power(8,i);//累加公式,i为指数
i++;
oct=oct/10;
}
result+=(oct%10)*power(8,i);//此时oct保存的是原来oct的最高位数,i也就为最大的指数了
return result;
}
int main()
{
for(int i=0;i<10;i++)
{
unsigned int oct=0;
unsigned int dec=0;
cout<<"输入一个8进制数:以0为高位开头标识"<<endl;
cin>>oct;
dec=oct2dec(oct);
cout<<"转换为十进制数是:"<<endl;
cout<<dec<<endl;
}
return 0;
}
上述程序经VC下测证通过。
通过此次实践正验证了一句话,实践是检验真理的唯一标准,书中的不一定全正确。