float面试题
如何用整数来模拟float or double型类型运算。
[解决办法]
问题不明确!什么叫模拟?
可以表示小数就可以了? 还是要准确的模拟浮点数的特性? 范围精度有没有要求?
[解决办法]
- C/C++ code
int x,y;int sum,fen;cout<<"Enter two number: ";cin>>x>>y;sum=x/y;fen=x%y;fen=(fen*10)/y;cout<<sum<<"."<<fen<<endl;
[解决办法]
例如:x=23,y=6
sum=x/y得出小数点前面的整数
fen=x%y得出x除y的余数
fen=(fen*10)/y 如果是小数点右边的值整型小于5是不会四舍五入的,所以余数乘以10,余数又能继续除以y
[解决办法]
char afloat[MAX] = {1,2,3,4,5}; //表示浮点数十进制形式的各个位
int iDot = 3; //表示小数点后面的第一位数的下标
这样小数就是123.45
[解决办法]
- C/C++ code
#include <stdio.h>#include <malloc.h>#include <iostream>using namespace std;/* int 型是4个字节 取值访问为 -2147483648 ~ 2147483647 对于10进制数来说,有9位的精度*/double pow10(int exp) //10的指数{ return pow(double(10), double(exp));}class newDouble{public: newDouble(void){bot=0; exp=0;}; newDouble( double d ) { bot =0; exp =0; int flag = d>0?1:-1; //取符号 d = abs(d); //取绝对值 while( d< pow10(8) && d!=0 ) //取8位精度 { d *= 10; exp--; } bot = flag*(int)(d); } newDouble operator+( newDouble b ) { (*this).SpecifyPrecision(7); //都指定7位的精度,相加不会越界 b.SpecifyPrecision(7); int dis = exp - b.exp; newDouble c; if( dis >0 ) { c.bot = (int)(bot*pow((double)10,(double)dis)) + b.bot; c.exp = b.exp; } else { c.bot = bot + (int)(b.bot*pow((double)10,(double)dis)); c.exp = exp; } return c; } newDouble operator-( newDouble b ) { (*this).SpecifyPrecision(7); //都指定7位的精度,相减不会越界 b.SpecifyPrecision(7); int dis = exp - b.exp; newDouble c; if( dis >0 ) { c.bot = (int)(bot*pow((double)10,(double)dis)) - b.bot; c.exp = b.exp; } else { c.bot = bot - (int)(b.bot*pow((double)10,(double)dis)); c.exp = exp; } return c; } newDouble operator*( newDouble b ) { (*this).SpecifyPrecision(4); //都指定4位的精度,相乘不会越界 b.SpecifyPrecision(3); newDouble c; c.bot = bot * b.bot; c.exp = exp + b.exp; return c; } newDouble operator/( newDouble b ) { if( b.bot ==0 ) { cout << "the divider can not be zero"<<endl; return newDouble(); } (*this).SpecifyPrecision(7); //被除数指定8位的精度 b.SpecifyPrecision(4); //除数指定4位精度 newDouble c; c.bot = bot / b.bot; c.exp = exp - b.exp; return c; } newDouble operator=( double d ) { bot =0; exp =0; int flag = d>0?1:-1; //取符号 d = abs(d); //取绝对值 while( d< pow10(8)&&d!=0 ) //取8位精度 { d *= 10; exp--; } bot = flag*(int)(d); return *this; //可以使用连等 } double ToDouble( newDouble b ) { return (double)(b.bot)*pow((double)10, (double)(b.exp)); } //指定精度,即底数的位数 void SpecifyPrecision( int num ) { if( bot ==0 ) return; int flag = bot>0?1:-1; bot = abs(bot); while( bot < pow10(num) ) { bot *= 10; exp--; } while( bot > pow10(num+1) ) { bot /=10; exp++; } bot = flag*bot; }private: int bot; int exp;};ostream & operator<<(ostream &out , newDouble d ) { out << d.ToDouble(d); return out; }int main(void){ newDouble a(50); newDouble b(8); cout << "a=" << a<<endl; cout << "b=" << b<<endl; cout <<"a+b=" << a+b <<endl; cout <<"a-b=" << a-b <<endl; cout <<"a*b=" << a*b <<endl; cout <<"a/b=" << a/b <<endl<<endl; a = -0.5; b = -0.03; cout << "a=" << a<<endl; cout << "b=" << b<<endl; cout <<"a+b=" << a+b <<endl; cout <<"a-b=" << a-b <<endl; cout <<"a*b=" << a*b <<endl; cout <<"a/b=" << a/b <<endl<<endl; a = 2.5; b = 4; cout << "a=" << a<<endl; cout << "b=" << b<<endl; cout << "(a*b)+(b-a)+(b/a)=" <<(a*b)+(b-a)+(b/a)<<endl<<endl; while(1) { double t=0; cout << "Please input a( double ): "<<endl; cin >> t; a =t; cout << "Please input b( double ): "<<endl; cin >> t; b =t; cout << "a=" << a<<endl; cout << "b=" << b<<endl; cout <<"a+b=" << a+b <<endl; cout <<"a-b=" << a-b <<endl; cout <<"a*b=" << a*b <<endl; cout <<"a/b=" << a/b <<endl<<endl; } return 0;}
[解决办法]
小数点忽略掉, 其实就是两个大整数互相计算, 最后把小数点放回去.
[解决办法]
- C/C++ code
#include<stdio.h>#define Max 50 //小数点位数,可自行定义位数int main(){int m,n,res,i;printf("输入被除数和除数:");scanf("%d%d",&m,&n);printf("%d.",m/n);//先输出整数部分和小数点 res=m%n;//取余数for(i=0;i<Max;i++){ res*=10;//余数乘10 printf("%d",res/n);// 余数乘10后再与除数相除,输出第i+1位小数 res=res%n;//取余数 if(0==res)//余数为0时说明除法结束,并退出,否则输出Max位小数 { break; }}printf("\n");return 0;}
[解决办法]
确实,ls说的不错,我觉得定义一个表示浮点数的结构体就行啦。
照样用整数加减,只有记住小数点就行了
[解决办法]
要效率的话:
1、用定点小数,可以用32位整形:高16位作为整数部分,低16位作为小数部分
范围大概 -32768 ~ 32767,精度 1/65536
加减法和整形一样,乘除法需要转化为64位整数运算,配合移位使用
2、使用分数形式,运算法则可以自己推倒