首页 > 代码库 > 一个Android实数转化二进制的计算器
一个Android实数转化二进制的计算器
导言:
这是我自己写的第一个小应用,没有什么优化,没有追求图标好看,就是搜索来的代码堆砌,等将来学完设计模式还有重构的话可能还会来改。
我觉得这个里面最考验我的就是小数转化为二进制的问题了,当然整数转二进制很容易,不过因为浮点数在计算机中的储存方式并不是正常人类思维的方式,因此我费了很大的力气才尽可能的实现了这样的模块。希望看到的读者有好的方法或是我的代码逻辑有错误,请不吝赐教,先谢过。
开始,新建项目-B2D(起反了)....一路默认就是了
构建界面
步骤1-声明应用的字符串在strings.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 4 <string name="app_name">二进制计算器</string> 5 <string name="action_settings">Settings</string> 6 <string name="hello_world">Hello world!</string> 7 <string name="one">1</string> 8 <string name="two">2</string> 9 <string name="three">3</string>10 <string name="four">4</string>11 <string name="five">5</string>12 <string name="six">6</string>13 <string name="seven">7</string>14 <string name="eight">8</string>15 <string name="nine">9</string>16 <string name="equal">=</string>17 <string name="clean">清屏</string>18 <string name="delete">CE</string>19 <string name="result"></string>20 <string name="hint1">输入十进制数</string>21 <string name="hint2">结果</string>22 <string name="point">.</string>23 <string name="zero">0</string>24 </resources>
主界面:
我是完全使用线性布局构建的主界面,将按钮等的大小都是定死了的,另外其他一些特殊属性譬如hint(提示)和右对齐等都是参考网上的。具体用法还请百度之。
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:id="@+id/LinearLayout1" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:orientation="vertical" 7 android:paddingBottom="@dimen/activity_vertical_margin" 8 android:paddingLeft="@dimen/activity_horizontal_margin" 9 android:paddingRight="@dimen/activity_horizontal_margin" 10 android:paddingTop="@dimen/activity_vertical_margin" 11 tools:context=".MainActivity" > 12 13 <EditText android:id="@+id/numEdit" 14 android:layout_width="match_parent" 15 android:layout_height="wrap_content" 16 android:text="" 17 android:hint="@string/hint1" 18 android:inputType="number" 19 android:enabled="false" 20 android:gravity="center_vertical|right"/> 21 22 <TextView android:id="@+id/showResult" 23 android:layout_width="match_parent" 24 android:layout_height="wrap_content" 25 android:padding="24dp" 26 android:text="@string/result" 27 android:hint="@string/hint2"/> 28 29 <LinearLayout 30 android:layout_width="match_parent" 31 android:layout_height="wrap_content" 32 android:orientation="horizontal" 33 android:gravity="center" > 34 35 <Button 36 android:id="@+id/one" 37 android:layout_width="72dp" 38 android:layout_height="72dp" 39 android:text="@string/one"/> 40 <Button 41 android:id="@+id/two" 42 android:layout_width="72dp" 43 android:layout_height="72dp" 44 android:text="@string/two"/> 45 46 <Button 47 android:id="@+id/three" 48 android:layout_width="72dp" 49 android:layout_height="72dp" 50 android:text="@string/three"/> 51 52 <Button 53 android:id="@+id/delete" 54 android:layout_width="72dp" 55 android:layout_height="72dp" 56 android:text="@string/delete"/> 57 </LinearLayout> 58 59 <LinearLayout 60 android:layout_width="match_parent" 61 android:layout_height="wrap_content" 62 android:orientation="horizontal" 63 android:gravity="center"> 64 65 <LinearLayout 66 android:layout_width="wrap_content" 67 android:layout_height="wrap_content" 68 android:orientation="vertical"> 69 70 <LinearLayout 71 android:layout_width="wrap_content" 72 android:layout_height="wrap_content" 73 android:orientation="horizontal"> 74 <Button 75 android:id="@+id/four" 76 android:layout_width="72dp" 77 android:layout_height="72dp" 78 android:text="@string/four"/> 79 80 <Button 81 android:id="@+id/five" 82 android:layout_width="72dp" 83 android:layout_height="72dp" 84 android:text="@string/five"/> 85 86 <Button 87 android:id="@+id/six" 88 android:layout_width="72dp" 89 android:layout_height="72dp" 90 android:text="@string/six"/> 91 </LinearLayout> 92 93 <LinearLayout 94 android:layout_width="wrap_content" 95 android:layout_height="wrap_content" 96 android:orientation="horizontal"> 97 <Button 98 android:id="@+id/seven" 99 android:layout_width="72dp"100 android:layout_height="72dp"101 android:text="@string/seven"/>102 103 <Button 104 android:id="@+id/eight"105 android:layout_width="72dp"106 android:layout_height="72dp"107 android:text="@string/eight"/>108 109 <Button 110 android:id="@+id/nine"111 android:layout_width="72dp"112 android:layout_height="72dp"113 android:text="@string/nine"/>114 </LinearLayout>115 116 </LinearLayout>117 118 <Button 119 android:id="@+id/equal"120 android:layout_width="72dp"121 android:layout_height="144dp"122 android:text="@string/equal"/>123 </LinearLayout>124 125 <LinearLayout 126 android:layout_width="match_parent"127 android:layout_height="wrap_content"128 android:gravity="center"129 android:orientation="horizontal">130 <Button 131 android:id="@+id/zero"132 android:layout_width="144dp"133 android:layout_height="72dp"134 android:text="@string/zero"/>135 <Button 136 android:id="@+id/point"137 android:layout_width="72dp"138 android:layout_height="72dp"139 android:text="@string/point"/>140 <Button 141 android:id="@+id/clean"142 android:layout_width="72dp"143 android:layout_height="72dp"144 android:text="@string/clean"/>145 </LinearLayout>146 147 </LinearLayout>
完成后的界面就是这样子:
当然我将文本编辑框的编辑功能干掉了,因为没有禁用的话会光标定位的时候会弹出系统输入法。
最后就是所有程序的逻辑代码了;
在onCreate我只是将所有逻辑处理分了两个函数init和OnListener
init是将全部自定义的变量与资源绑定:
1 /*输入文本框*/ 2 private EditText numEditText; 3 4 /*显示结果*/ 5 private TextView showResultTextView; 6 7 /*数字按钮*/ 8 private Button oneButton; 9 private Button twoButton;10 private Button threeButton;11 private Button fourButton;12 private Button fiveButton;13 private Button sixButton;14 private Button sevenButton;15 private Button eightButton;16 private Button nineButton;17 private Button zeroButton;18 private Button pointButton;19 20 /*操作按钮*/21 private Button equalButton;22 private Button ceButton;23 private Button delButton;24 25 private void init(){26 /*初始化组件*/27 numEditText=(EditText)findViewById(R.id.numEdit);28 29 showResultTextView=(TextView)findViewById(R.id.showResult);30 31 oneButton=(Button)findViewById(R.id.one);32 twoButton=(Button)findViewById(R.id.two);33 threeButton=(Button)findViewById(R.id.three);34 fourButton=(Button)findViewById(R.id.four);35 fiveButton=(Button)findViewById(R.id.five);36 sixButton=(Button)findViewById(R.id.six);37 sevenButton=(Button)findViewById(R.id.seven);38 eightButton=(Button)findViewById(R.id.eight);39 nineButton=(Button)findViewById(R.id.nine);40 zeroButton=(Button)findViewById(R.id.zero);41 42 pointButton=(Button)findViewById(R.id.point);43 equalButton=(Button)findViewById(R.id.equal);44 ceButton=(Button)findViewById(R.id.delete);45 delButton=(Button)findViewById(R.id.clean);46 47 }
然后就是为所有按钮添加监听,我做的比较麻烦,就是一个一个按钮添加的监听,应该可以把重复的代码封到一个函数中,将来优化吧。
1 private void OnListener(){ 2 /*设置监听*/ 3 4 /*等号的处理*/ 5 equalButton.setOnClickListener(new View.OnClickListener() { 6 7 @Override 8 public void onClick(View v) { 9 // TODO Auto-generated method stub 10 double result; 11 if(numString!=""){ 12 result=Double.parseDouble(numString); 13 resultString=dec2bin(result); 14 } 15 16 showResultTextView.setText(resultString); 17 } 18 }); 19 20 /*设置对CE的监听*/ 21 ceButton.setOnClickListener(new View.OnClickListener() { 22 23 @Override 24 public void onClick(View v) { 25 // TODO Auto-generated method stub 26 String s=""; 27 if(numString.length()!=0){ 28 29 /*获取将要被删除的字符*/ 30 s=numString.substring(numString.length()-1); 31 32 /*判断是否为.,若是则将小数点标志位置否,且将小数位数指0*/ 33 if(s.equals(".")){ 34 isPoint=false; 35 count=0; 36 } 37 //如果是在小数部分删除,计数减一 38 if(isPoint){ 39 --count; 40 } 41 42 numString=numString.substring(0, numString.length()-1); 43 } 44 numEditText.setText(numString); 45 } 46 }); 47 48 /*设置对DEL的监听*/ 49 delButton.setOnClickListener(new View.OnClickListener() { 50 51 @Override 52 public void onClick(View v) { 53 // TODO Auto-generated method stub 54 numString=""; 55 resultString=""; 56 numEditText.setText(numString); 57 showResultTextView.setText(resultString); 58 isPoint=false; 59 count=0; 60 } 61 }); 62 63 /*对数字按钮的监听*/ 64 oneButton.setOnClickListener(new View.OnClickListener() { 65 66 @Override 67 public void onClick(View v) { 68 // TODO Auto-generated method stub 69 if(isPoint){ 70 ++count; 71 } 72 numString+="1"; 73 numEditText.setText(numString); 74 } 75 }); 76 77 twoButton.setOnClickListener(new View.OnClickListener() { 78 79 @Override 80 public void onClick(View v) { 81 // TODO Auto-generated method stub 82 if(isPoint){ 83 ++count; 84 } 85 numString+="2"; 86 numEditText.setText(numString); 87 } 88 }); 89 90 threeButton.setOnClickListener(new View.OnClickListener() { 91 92 @Override 93 public void onClick(View v) { 94 // TODO Auto-generated method stub 95 if(isPoint){ 96 ++count; 97 } 98 numString+="3"; 99 numEditText.setText(numString);100 }101 });102 103 fourButton.setOnClickListener(new View.OnClickListener() {104 105 @Override106 public void onClick(View v) {107 // TODO Auto-generated method stub108 if(isPoint){109 ++count;110 }111 numString+="4";112 numEditText.setText(numString);113 }114 });115 116 fiveButton.setOnClickListener(new View.OnClickListener() {117 118 @Override119 public void onClick(View v) {120 // TODO Auto-generated method stub121 if(isPoint){122 ++count;123 }124 numString+="5";125 numEditText.setText(numString);126 }127 });128 129 sixButton.setOnClickListener(new View.OnClickListener() {130 131 @Override132 public void onClick(View v) {133 // TODO Auto-generated method stub134 if(isPoint){135 ++count;136 }137 numString+="6";138 numEditText.setText(numString);139 }140 });141 142 sevenButton.setOnClickListener(new View.OnClickListener() {143 144 @Override145 public void onClick(View v) {146 // TODO Auto-generated method stub147 if(isPoint){148 ++count;149 }150 numString+="7";151 numEditText.setText(numString);152 }153 });154 155 eightButton.setOnClickListener(new View.OnClickListener() {156 157 @Override158 public void onClick(View v) {159 // TODO Auto-generated method stub160 if(isPoint){161 ++count;162 }163 numString+="8";164 numEditText.setText(numString);165 }166 });167 168 nineButton.setOnClickListener(new View.OnClickListener() {169 170 @Override171 public void onClick(View v) {172 // TODO Auto-generated method stub173 if(isPoint){174 ++count;175 }176 numString+="9";177 numEditText.setText(numString);178 }179 });180 181 zeroButton.setOnClickListener(new View.OnClickListener() {182 183 @Override184 public void onClick(View v) {185 // TODO Auto-generated method stub186 if(isPoint){187 ++count;188 }189 numString+="0";190 numEditText.setText(numString);191 }192 });193 194 pointButton.setOnClickListener(new View.OnClickListener() {195 196 @Override197 public void onClick(View v) {198 // TODO Auto-generated method stub199 if(isPoint==false){200 numString+=".";201 numEditText.setText(numString);202 isPoint=true;203 }204 }205 });206 }
这里面有很多东西是新加上的:
变量,大部分主要是为了方便计算小数的二进制。
1 /*显示输入框中的文本*/ 2 private String numString=""; 3 4 /*设置小数点是否已经使用的标志*/ 5 private boolean isPoint=false; 6 7 /*为了保存精度,需要记录输入的小数位数*/ 8 private int count=0; 9 10 //保存计算结果11 private String resultString="";
主要逻辑大概就是:
1.按下数字0-9按钮的时候首先判断是否在小数点之后(就是是不是已经有了小数点),因为我们输入数字的时候只能输入一个小数点,那么如果在小数点之后就将记录小数位数的count加1;
2.按下CE按钮的时候先判断是否文本框中有字符(没字符当然就删不了了);
.然后判断要被删的是否是小数点,是的话将标示小数点是否存在的isPoint置否。
.之后删除文本框中显示的最后一个字符
3.按下清屏按钮的时候将所有可能影响的东西初始化,譬如小数点标记和小数点位数计数;
4.按下等号的时候只需要将文本框中已经输入的数字转化为浮点数传递给处理函数了;
最后是最重要的函数了,就是那个dec2bin的处理函数
先放代码:
1 private String dec2bin(double num){ 2 3 String resultString=""; 4 5 //位数限制 6 int preCount=16; 7 8 //取整数部分的二进制表示 9 int intPart=(int)num;10 //保存副本11 int intPartSaved=intPart;12 13 String intString="";14 15 if(intPart==0){16 intString="0";17 }else{18 intString="";19 while(intPart!=0){20 int m=intPart%2;21 if(m==0){22 intString+="0";23 }24 if(m==1){25 intString+="1";26 }27 intPart/=2;28 }29 intString=new StringBuilder(intString).reverse().toString();30 }31 32 resultString+=intString;33 34 if(isPoint){35 resultString+="."; 36 37 //取小数部分的二进制表示38 int base=1;39 while(count!=0){40 base*=10;41 --count;42 }43 44 num*=base;45 46 int decPart=(int)(num-intPartSaved*base);47 48 String decString="";49 50 while(decPart!=0 && preCount!=0){51 52 decPart*=2;53 //取进位54 int n=decPart/base;55 //取余56 decPart=decPart%base;57 58 if(n==1){59 decString+="1";60 }61 if(n==0){62 decString+="0";63 }64 --preCount;65 }66 67 resultString+=decString;68 }69 70 return resultString;71 }
思路:
先取出浮点数中的整数部分,然后进行转化为二进制,这很简单,当然记住转换的时候余数倒序才是整数的二进制表示。
之后是对小数部分的处理:
为了将小数部分分离出来,我首先想到将原浮点数减去整数部分,当然,对于一些数字得到了正确结果,但是:
在测试12.152的时候出现了类似这样的输出
0.15199999999999925
Java中测试代码:
double i=12.152;double a=i-(int)i;System.out.print(a);
这样就为我转换造成了障碍,为了克服这个,
我根据关于此问题在某论坛中的讨论考虑到是否可以将有限小数的浮点数先转化为整数呢?这样就可以克服小数存储的精度问题了?
事实证明方法可行,
因此我才在上面添加了小数位数计数变量,
这样我就可以在处理中按照小数位数乘上基数10的幂方来扩大浮点数,这样就得到了用整数表达的小数。
之后发逻辑很简单,按照小数转化二进制的方式,将最高位视为小数点前面那位,
如此可以按照小数转化的方式求出各位,顺序排列到字符串中就可以了,最后将结果连接然后输出到文本显示组件上。
最后出现的问题是图标的问题,要使用自定义的图标仅仅将原文件夹下的图标用同名覆盖是不够的,需要在AndroidManifest.xml下修改这一句:
android:icon="@drawable/cal"
cal就是我放的图标文件名,当然此处注意不需要加.png的扩展名。
然后就完成了;下面贴下Java完整代码:
1 package com.lhyz.b2d; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.Menu; 6 import android.view.View; 7 import android.widget.Button; 8 import android.widget.EditText; 9 import android.widget.TextView; 10 11 public class MainActivity extends Activity { 12 /*输入文本框*/ 13 private EditText numEditText; 14 15 /*显示结果*/ 16 private TextView showResultTextView; 17 18 /*数字按钮*/ 19 private Button oneButton; 20 private Button twoButton; 21 private Button threeButton; 22 private Button fourButton; 23 private Button fiveButton; 24 private Button sixButton; 25 private Button sevenButton; 26 private Button eightButton; 27 private Button nineButton; 28 private Button zeroButton; 29 private Button pointButton; 30 31 /*操作按钮*/ 32 private Button equalButton; 33 private Button ceButton; 34 private Button delButton; 35 36 /*显示输入框中的文本*/ 37 private String numString=""; 38 39 /*设置小数点是否已经使用的标志*/ 40 private boolean isPoint=false; 41 42 /*为了保存精度,需要记录输入的小数位数*/ 43 private int count=0; 44 45 //保存计算结果 46 private String resultString=""; 47 48 49 @Override 50 protected void onCreate(Bundle savedInstanceState) { 51 super.onCreate(savedInstanceState); 52 setContentView(R.layout.activity_main); 53 54 init(); 55 56 OnListener(); 57 58 } 59 60 private void init(){ 61 /*初始化组件*/ 62 numEditText=(EditText)findViewById(R.id.numEdit); 63 64 showResultTextView=(TextView)findViewById(R.id.showResult); 65 66 oneButton=(Button)findViewById(R.id.one); 67 twoButton=(Button)findViewById(R.id.two); 68 threeButton=(Button)findViewById(R.id.three); 69 fourButton=(Button)findViewById(R.id.four); 70 fiveButton=(Button)findViewById(R.id.five); 71 sixButton=(Button)findViewById(R.id.six); 72 sevenButton=(Button)findViewById(R.id.seven); 73 eightButton=(Button)findViewById(R.id.eight); 74 nineButton=(Button)findViewById(R.id.nine); 75 zeroButton=(Button)findViewById(R.id.zero); 76 77 pointButton=(Button)findViewById(R.id.point); 78 equalButton=(Button)findViewById(R.id.equal); 79 ceButton=(Button)findViewById(R.id.delete); 80 delButton=(Button)findViewById(R.id.clean); 81 82 } 83 84 private String dec2bin(double num){ 85 86 String resultString=""; 87 88 //位数限制 89 int preCount=16; 90 91 //取整数部分的二进制表示 92 int intPart=(int)num; 93 //保存副本 94 int intPartSaved=intPart; 95 96 String intString=""; 97 98 if(intPart==0){ 99 intString="0";100 }else{101 intString="";102 while(intPart!=0){103 int m=intPart%2;104 if(m==0){105 intString+="0";106 }107 if(m==1){108 intString+="1";109 }110 intPart/=2;111 }112 intString=new StringBuilder(intString).reverse().toString();113 }114 115 resultString+=intString;116 117 if(isPoint){118 resultString+="."; 119 120 //取小数部分的二进制表示121 int base=1;122 while(count!=0){123 base*=10;124 --count;125 }126 127 num*=base;128 129 int decPart=(int)(num-intPartSaved*base);130 131 String decString="";132 133 while(decPart!=0 && preCount!=0){134 135 decPart*=2;136 //取进位137 int n=decPart/base;138 //取余139 decPart=decPart%base;140 141 if(n==1){142 decString+="1";143 }144 if(n==0){145 decString+="0";146 }147 --preCount;148 }149 150 resultString+=decString;151 }152 153 return resultString;154 }155 156 private void OnListener(){157 /*设置监听*/158 159 /*等号的处理*/160 equalButton.setOnClickListener(new View.OnClickListener() {161 162 @Override163 public void onClick(View v) {164 // TODO Auto-generated method stub165 double result;166 if(numString!=""){167 result=Double.parseDouble(numString);168 resultString=dec2bin(result);169 }170 171 showResultTextView.setText(resultString);172 }173 });174 175 /*设置对CE的监听*/176 ceButton.setOnClickListener(new View.OnClickListener() {177 178 @Override179 public void onClick(View v) {180 // TODO Auto-generated method stub181 String s="";182 if(numString.length()!=0){183 184 /*获取将要被删除的字符*/185 s=numString.substring(numString.length()-1);186 187 /*判断是否为.,若是则将小数点标志位置否,且将小数位数指0*/188 if(s.equals(".")){189 isPoint=false;190 count=0;191 }192 //如果是在小数部分删除,计数减一193 if(isPoint){194 --count;195 }196 197 numString=numString.substring(0, numString.length()-1);198 }199 numEditText.setText(numString);200 }201 });202 203 /*设置对DEL的监听*/204 delButton.setOnClickListener(new View.OnClickListener() {205 206 @Override207 public void onClick(View v) {208 // TODO Auto-generated method stub209 numString="";210 resultString="";211 numEditText.setText(numString);212 showResultTextView.setText(resultString);213 isPoint=false;214 count=0;215 }216 });217 218 /*对数字按钮的监听*/219 oneButton.setOnClickListener(new View.OnClickListener() {220 221 @Override222 public void onClick(View v) {223 // TODO Auto-generated method stub224 if(isPoint){225 ++count;226 }227 numString+="1";228 numEditText.setText(numString);229 }230 });231 232 twoButton.setOnClickListener(new View.OnClickListener() {233 234 @Override235 public void onClick(View v) {236 // TODO Auto-generated method stub237 if(isPoint){238 ++count;239 }240 numString+="2";241 numEditText.setText(numString);242 }243 });244 245 threeButton.setOnClickListener(new View.OnClickListener() {246 247 @Override248 public void onClick(View v) {249 // TODO Auto-generated method stub250 if(isPoint){251 ++count;252 }253 numString+="3";254 numEditText.setText(numString);255 }256 });257 258 fourButton.setOnClickListener(new View.OnClickListener() {259 260 @Override261 public void onClick(View v) {262 // TODO Auto-generated method stub263 if(isPoint){264 ++count;265 }266 numString+="4";267 numEditText.setText(numString);268 }269 });270 271 fiveButton.setOnClickListener(new View.OnClickListener() {272 273 @Override274 public void onClick(View v) {275 // TODO Auto-generated method stub276 if(isPoint){277 ++count;278 }279 numString+="5";280 numEditText.setText(numString);281 }282 });283 284 sixButton.setOnClickListener(new View.OnClickListener() {285 286 @Override287 public void onClick(View v) {288 // TODO Auto-generated method stub289 if(isPoint){290 ++count;291 }292 numString+="6";293 numEditText.setText(numString);294 }295 });296 297 sevenButton.setOnClickListener(new View.OnClickListener() {298 299 @Override300 public void onClick(View v) {301 // TODO Auto-generated method stub302 if(isPoint){303 ++count;304 }305 numString+="7";306 numEditText.setText(numString);307 }308 });309 310 eightButton.setOnClickListener(new View.OnClickListener() {311 312 @Override313 public void onClick(View v) {314 // TODO Auto-generated method stub315 if(isPoint){316 ++count;317 }318 numString+="8";319 numEditText.setText(numString);320 }321 });322 323 nineButton.setOnClickListener(new View.OnClickListener() {324 325 @Override326 public void onClick(View v) {327 // TODO Auto-generated method stub328 if(isPoint){329 ++count;330 }331 numString+="9";332 numEditText.setText(numString);333 }334 });335 336 zeroButton.setOnClickListener(new View.OnClickListener() {337 338 @Override339 public void onClick(View v) {340 // TODO Auto-generated method stub341 if(isPoint){342 ++count;343 }344 numString+="0";345 numEditText.setText(numString);346 }347 });348 349 pointButton.setOnClickListener(new View.OnClickListener() {350 351 @Override352 public void onClick(View v) {353 // TODO Auto-generated method stub354 if(isPoint==false){355 numString+=".";356 numEditText.setText(numString);357 isPoint=true;358 }359 }360 });361 }362 363 364 @Override365 public boolean onCreateOptionsMenu(Menu menu) {366 // Inflate the menu; this adds items to the action bar if it is present.367 getMenuInflater().inflate(R.menu.main, menu);368 return true;369 }370 371 }
done.
一个Android实数转化二进制的计算器