1. java使用LinkedList進行大數相加,求指點。。。
public
static void main(String[] args) {
// TODO Auto-generated method stub
List<Integer> bigNumber =
new LinkedList<Integer>();
for(int i = 0; i <30; i++) {
bigNumber.add(7);
}
List<Integer> bigNumber1 =
new LinkedList<Integer>();
for(int i = 0; i < 30; i++) {
bigNumber1.add(6);
}
System.
out.println("bigNumber:"+bigNumber);
System.
out.println("bigNumber1:"+bigNumber1);
List<Integer> m = addMethod(bigNumber, bigNumber1);
for(int i = m.size()-1; i >=0; i--){ //因為是順著放進去的,所以應該倒著取出來。
System.
out.print(m.get(i));
}
}
public static List<Integer> addMethod(List<Integer> a, List<Integer> b) {
List<Integer> sum =
new LinkedList<Integer>();
int ii = 0; //存儲十位上的數
for(int i = 0; i < 30; i++) {
int temp;
if(ii > 0){
temp = a.get(i) + b.get(i) + ii;
//當十位上有數字是就應該加上
ii = 0;
}
else{
temp = a.get(i) + b.get(i);
}
if(temp >= 10) {
int u = temp%10;
int y = temp/10;
sum.add(u);
ii = y;
if(i == 29){ //當加到最後一位時,應該把十位也放進結果里
sum.add(ii);
}
}
else {
sum.add(temp);
}
}
return sum;
}
2. java 兩數相加 計算代碼 給個答案唄
public class Operation{
public int operation(int a,int b){
return a+b;
}
}
這是簡單計算兩數方法,先創建這個對象然後調用其中operation這個方法,傳輸你要想要計算的參數就可以得到答案了如 new Operation().operation(1,3)得到答案4雖然沒編譯應該沒問題
3. java怎麼處理大數相加
package eshop.framework.util;
import java.math.BigDecimal;
public class AmountUtil {
// 默認除法運算精度
private static final int DEFAULT_DIV_SCALE = 2;
/**
* 提供精確的加法運算。
*
* @param v1
* @param v2
* @return 兩個參數的和
*/
public static double add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精確的加法運算
*
* @param v1
* @param v2
* @return 兩個參數數學加和,以字元串格式返回
*/
public static String add(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.add(b2).toString();
}
/**
* 提供精確的減法運算。
*
* @param v1
* @param v2
* @return 兩個參數的差
*/
public static double subtract(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精確的減法運算
*
* @param v1
* @param v2
* @return 兩個參數數學差,以字元串格式返回
*/
public static String subtract(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.subtract(b2).toString();
}
/**
* 提供精確的乘法運算。
*
* @param v1
* @param v2
* @return 兩個參數的積
*/
public static double multiply(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供精確的乘法運算
*
* @param v1
* @param v2
* @return 兩個參數的數學積,以字元串格式返回
*/
public static String multiply(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.multiply(b2).toString();
}
/**
* 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到 小數點以後2位,以後的數字四捨五入,舍入模式採用ROUND_HALF_EVEN
*
* @param v1
* @param v2
* @return 兩個參數的商
*/
public static double divide(double v1, double v2) {
return divide(v1, v2, DEFAULT_DIV_SCALE);
}
/**
* 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指 定精度,以後的數字四捨五入。舍入模式採用ROUND_HALF_EVEN
*
* @param v1
* @param v2
* @param scale
* 表示需要精確到小數點以後幾位。
* @return 兩個參數的商
*/
public static double divide(double v1, double v2, int scale) {
return divide(v1, v2, scale, BigDecimal.ROUND_HALF_EVEN);
}
/**
* 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指 定精度,以後的數字四捨五入。舍入模式採用用戶指定舍入模式
*
* @param v1
* @param v2
* @param scale
* 表示需要精確到小數點以後幾位
* @param round_mode
* 表示用戶指定的舍入模式
* @return 兩個參數的商
*/
public static double divide(double v1, double v2, int scale, int round_mode) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, round_mode).doubleValue();
}
/**
* 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到 小數點以後10位,以後的數字四捨五入,舍入模式採用ROUND_HALF_EVEN
*
* @param v1
* @param v2
* @return 兩個參數的商,以字元串格式返回
*/
public static String divide(String v1, String v2) {
return divide(v1, v2, DEFAULT_DIV_SCALE);
}
/**
* 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指 定精度,以後的數字四捨五入。舍入模式採用ROUND_HALF_EVEN
*
* @param v1
* @param v2
* @param scale
* 表示需要精確到小數點以後幾位
* @return 兩個參數的商,以字元串格式返回
*/
public static String divide(String v1, String v2, int scale) {
return divide(v1, v2, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_EVEN);
}
/**
* 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指 定精度,以後的數字四捨五入。舍入模式採用用戶指定舍入模式
*
* @param v1
* @param v2
* @param scale
* 表示需要精確到小數點以後幾位
* @param round_mode
* 表示用戶指定的舍入模式
* @return 兩個參數的商,以字元串格式返回
*/
public static String divide(String v1, String v2, int scale, int round_mode) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.divide(b2, scale, round_mode).toString();
}
/**
* 提供精確的小數位四捨五入處理,舍入模式採用ROUND_HALF_EVEN
*
* @param v
* 需要四捨五入的數字
* @param scale
* 小數點後保留幾位
* @return 四捨五入後的結果
*/
public static double round(double v, int scale) {
return round(v, scale, BigDecimal.ROUND_HALF_EVEN);
}
/**
* 提供精確的小數位四捨五入處理
*
* @param v
* 需要四捨五入的數字
* @param scale
* 小數點後保留幾位
* @param round_mode
* 指定的舍入模式
* @return 四捨五入後的結果
*/
public static double round(double v, int scale, int round_mode) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
return b.setScale(scale, round_mode).doubleValue();
}
/**
* 提供精確的小數位四捨五入處理,舍入模式採用ROUND_HALF_EVEN
*
* @param v
* 需要四捨五入的數字
* @param scale
* 小數點後保留幾位
* @return 四捨五入後的結果,以字元串格式返回
*/
public static String round(String v, int scale) {
return round(v, scale, BigDecimal.ROUND_HALF_EVEN);
}
/**
* 提供精確的小數位四捨五入處理
*
* @param v
* 需要四捨五入的數字
* @param scale
* 小數點後保留幾位
* @param round_mode
* 指定的舍入模式
* @return 四捨五入後的結果,以字元串格式返回
*/
public static String round(String v, int scale, int round_mode) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(v);
return b.setScale(scale, round_mode).toString();
}
public static String doubleToString(double num, int scale, int round_mode) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(num);
return b.setScale(scale, round_mode).toString();
}
}
4. 用 Java 寫一個兩個整數相加的程序
代碼如下:
public class Test {
public static int add(int a,int b){
return a+b;
}
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入第一個數");
int a = scanner.nextInt();
System.out.println("請輸入第二個數");
int b = scanner.nextInt();
System.out.println("和為:"+add(a,b));
}
}
運算符
運算符是一些特殊的符號,主要用於數學函數、一些類型的賦值語句和邏輯比較方面。
1、賦值運算符
賦值運算符以符號「=」表示,它是一個二元運算符(對兩個操作數作處理),其功能是將右方操作數所含的值賦給左方的操作數。
例如:
1 int a = 100;
2、算術運算符
運算符說明 :
「+」 加 ;「-」 減 ;「*」 乘 ; 「/」除 ; 「%」 取余數
3、自增和自減運算符
自增和自減是單目運算符,可以放在操作元之前,也可以放在操作元之後。操作元必須是一個整型或浮點型變數。自增、自減運算符的作用是使變數的值增1或減1。放在操作元前面的自增、自減運算符,會先將變數的值加1或減1,然後再使該變數參與表達式的運算。放在操作元後面的自增、自減運算符,會先使變數參與表達式的運算,然後再將該變數的值加1或減1。
例如:
假設a=5
1 b=++a;//先將a的值加1,然後賦值給b,此時a的值為6,b的值為6
2 b=a++;//先將a的值賦值給b,再將a的值變為6,此時a的值為6,b的值為5
4、比較運算符
比較運算符屬於二元運算符,用於程序中的變數之間,變數和自變數之間以及其他類型的信息之間的比較。比較運算符的運算結果是boolean型。當運算符對應的關系成立時,運算的結果為true,否則為false。比較運算符共有6個,通常作為判斷的依據用於條件語句中。
運算符說明:
">"比較左方是否大於右方
"<"比較左方是否小於右方
"=="比較左方是否等於右方
"> = "比較左方是否大於等於右方
"<= "比較左方是否小於等於右方
"!= "比較左方是否不等於右方
參考鏈接:Java(計算機編程語言)_網路
5. java數組實現大數相加
package com.nileader.big.entity;
public class BigInt {
private String data_str; //原始數據
private int digit; //數據位數
private int[] data; //大數
private boolean carry = false; //進位標識符
/**
* setter and getter
*/
public boolean isCarry() {
return carry;
}
public void setCarry(boolean carry) {
this.carry = carry;
}
public String getData_str() {
return data_str;
}
public void setData_str(String data_str) {
this.data_str = data_str;
}
public int[] getData() {
return data;
}
public void setData(int[] data) {
this.data = data;
}
public int getDigit() {
return digit;
}
public void setDigit(int digit) {
this.digit = digit;
}
//構造方法
public BigInt(){};
public BigInt(String str_data)
{
this.setData_str(str_data);
}
//基本操作
/**
* 形成大數 初始化
*/
public void initBInt()
{
this.setDigit( this.getData_str().length() );
this.data = new int[this.getDigit()];
//將字元組成的大數逆序放入int[] data中
for(int i = 0, j=this.getDigit() ; i
{
// 1104 --> data[0] = '4',data[1] = '0',data[2]=1, data[3]= '1'
this.data[i] = Integer.parseInt( this.getData_str().substring(j-1,j) );
}
}
/**
* 進行大數相加操作
*/
public void add( BigInt bint)
{
//this的位數大於bint的位數
if( this.getDigit() < bint.getDigit() )
{
int[] datatemp = this.getData();
this.setData( bint.getData());
bint.setData( datatemp);
this.setDigit(this.getData().length);
bint.setDigit(bint.getData().length);
}
//將短的那個先加完
int i =0;
for(; i
{
int tdata = 0;
//上次運算有進位
if( this.isCarry())
{
tdata = this.getData()[i] + bint.getData()[i] +1;
//取消進位標識
this.setCarry(false);
}
else tdata = this.getData()[i] + bint.getData()[i] ;
//本次結果無進位
if(tdata <10) this.data[i] = tdata;
//本次結果有進位
else if(tdata >=10)
{
this.data[i] = tdata -10;
this.setCarry(true);
}
} //短的那個加完了
//剩餘數的處理
for(;i
{
//有個進位的
if(this.isCarry())
{
int tdata = this.data[i]+1;
if(tdata >=10) this.data[i] = tdata -10;
else
{
this.data[i] = tdata;
this.setCarry(false);
}
}
}
//對最高位益處檢測
if(this.data[this.getDigit()-1] == 0)
{
int[] tdata = new int[this.getDigit()+1];
System.array(this.getData(), 0, tdata, 0, this.getDigit());
tdata[this.getDigit()] = 1;
this.setData(tdata);
}
}
}
其中代碼段
//對最高位益處檢測
if(this.data[this.getDigit()-1] == 0)
{
int[] tdata = new int[this.getDigit()+1];
System.array(this.getData(), 0, tdata, 0, this.getDigit());
tdata[this.getDigit()] = 1;
this.setData(tdata);
}
6. java 很長的大數 如何用String 相加,相乘
相加比較簡單,用單層循環就能實現。進位的話因為加法只存在進1和不進兩種情況,用一個boolean型標記一下就能實現。
相乘的有難度。
7. 語言Java 構造一個大數類 要求實現相加 比較 輸出
public class BigNumber { public static int[] add(int[] a, int[] b) { int carry = 0; int[] c = new int[a.length]; for(int i = a.length - 1; i >= 0; i--) { c[i] = a[i] + b[i] + carry; if(c[i] < 10000) carry = 0; else { // 進位 c[i] = c[i] - 10000; carry = 1; } } return c; } public static int[] sub(int[] a, int[] b) { int borrow = 0; int[] c = new int[a.length]; for(int i = a.length - 1; i >= 0; i--) { c[i] = a[i] - b[i] - borrow; if(c[i] >= 0) borrow = 0; else { // 借位 c[i] = c[i] + 10000; borrow = 1; } } return c; } public static int[] mul(int[] a, int b) { // b 為乘數 int carry = 0; int[] c = new int[a.length]; for(int i = a.length - 1; i >=0; i--) { int tmp = a[i] * b + carry; c[i] = tmp % 10000; carry = tmp / 10000; } return c; } public static int[] div(int[] a, int b) { // b 為除數 int remain = 0; int[] c = new int[a.length]; for(int i = 0; i < a.length; i++) { int tmp = a[i] + remain; c[i] = tmp / b; remain = (tmp % b) * 10000; } return c; } public static void main(String[] args) { int[] a = {1234, 5678, 9910, 1923, 1124}; int[] b = {1234, 5678, 9910, 1923, 1124}; int[] c = BigNumber.add(a, b); for(int i = 0; i < c.length; i++) { System.out.print(c[i]); } System.out.println(); }}
8. 求JAVA代碼,要求輸入兩個數,實現超大數的相加和相減
package test;
public class DoubleTest {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(Long.MAX_VALUE);//最大數:9223372036854775807
System.out.println(Long.MIN_VALUE);//最小數:-9223372036854775808
System.out.println(Double.MAX_VALUE);//最大數:1.7976931348623157E308
System.out.println(Double.MIN_VALUE);//最小數:4.9E-324
Double a = 9223372036854775807d;
Double b = 9223372036854775807d;
Double c =a+b;
System.out.println(c);
}
}
用Double型吧。最大了。
9. 用JAVA線性表來編寫「任意大的整數相加減」
虛擬化浪潮
VMware虛擬化
微軟虛擬化
IBM虛擬化
HP虛擬化
SWsoft虛擬化
SUN虛擬化
Intel虛擬化
AMD虛擬化
Java虛擬機
通過軟體模擬的具有完整硬體系統功能的、運行在一個完全隔離環境中的完整計算機系統。通過虛擬機軟體,你可以在一台物理計算機上模擬出一台或多台虛擬的計算機,這些虛擬機[1]完全就像真正的計算機那樣進行工作,例如你可以安裝操作系統、安裝應用程序、訪問網路資源等等。對於你而言,它只是運行在你物理計算機上的一個應用程序,但是對於在虛擬機中運行的應用程序而言,它就像是在真正的計算機中進行工作。因此,當我在虛擬機中進行軟體評測時,可能系統一樣會崩潰,但是,崩潰的只是虛擬機上的操作系統,而不是物理計算機上的操作系統,並且,使用虛擬機的「Undo」(恢復)功能,我可以馬上恢復虛擬機到安裝軟體之前的狀態。
目前流行的虛擬機軟體有VMware(VMWare ACE)和Virtual PC,它們都能在Windows系統上虛擬出多個計算機,用於安裝Linux、OS/2、FreeBSD等其他操作系統。微軟在2003年2月份收購Connectix後,很快發布了Microsoft Virtual PC 2004。但出於種種考慮,新發布的Virtual PC 2004已不再明確支持Linux、FreeBSD、NetWare、Solaris等操作系統,只保留了OS/2,如果要虛擬一台Linux計算機,只能自己手工設置。相比而言,VMware不論是在多操作系統的支持上,還是在執行效率上,都比Virtual PC 2004明顯高出一籌,這也是本文選擇它的理由之一。
電腦一台變兩台,學用Linux不再有後顧之憂
VMware 4.5有Workstation、GSX server等多種版本,其中Windows版的Workstation應用最廣,本文即以它為基礎進行各種實戰演習。
虛擬機的概念比較寬泛,通常人們接觸到的虛擬機概念有VMware那樣的硬體模擬軟體,也有JVM這樣的介於硬體和編譯程序之間的軟體。這里所指的是後者。
虛擬機是一個抽象的計算機,和實際的計算機一樣,具有一個指令集並使用不同的存儲區域。它負責執行指令,還要管理數據、內存和寄存器。這台虛擬的機器在任何平台上都提供給編譯程序一個的共同的介面。編譯程序只需要面向虛擬機,生成虛擬機能夠理解的代碼,然後由解釋器來將虛擬機代碼轉換為特定系統的機器碼執行。
Sun xVM VirtualBox又發新版本:2.1.0。
2.1.0不像此前2.0.X一樣主要是修正Bug和完善原有功能,這個版本增加了許多新特性。強烈建議VBox的用戶們更新!
在官方網站的ChangeLog上,我們可以看到這個版本的主要更新信息:
* 支持Max OS X客戶機的硬體虛擬化技術(VT-x和AMD-V);
* 支持在32位操作系統上模擬64位客戶機!(實驗性質,具體看用戶手冊);
* 支持Intel Nehalem虛擬化增強技術(EPT和VPID,具體看用戶手冊);
* 通過OpenGL支持3D加速!(看用戶手冊4.8章);
還有很多更新,但是光是以上四樣就有足夠地理由讓用戶去升級了!
VirtualBox終於支持了通過OpenGL實驗的的3D加速,並且率先支持了在32位的操作系統上模擬64位的客戶機(需要64位CPU支持)。這意味著虛擬機平台的限制更少了,你可以在你的x86平台上模擬AMD64!
針對「OpenGL 3D加速」這一項,我了解到,這項特性目前只在Windows系統上可用,並且只能實現OpenGL加速,而沒有Direct3D加速。這意味著,你已經可以在Windows虛擬機運行一些OpenGL的3D應用,而Direct3D就要稍微等等了。
還等什麼呢,這是一個進步相當大的版本。趕緊下載試用吧:
個人為什麼使用虛擬機
1. 演示環境,可以安裝各種演示環境,便於做各種例子;
2. 保證主機的快速運行,減少不必要的垃圾安裝程序,偶爾使用的程序,或者測試用的程序在虛擬機上運行;
3. 避免每次重新安裝,銀行等常用工具,不經常使用,而且要求保密比較好的,單獨在一個環境下面運行;
4. 想測試一下不熟悉的應用,在虛擬機中隨便安裝和徹底刪除;
5. 體驗不同版本的操作系統,如Linux、Mac等。
!820C63A54759569D!965.entry
Java虛擬機
一、什麼是Java虛擬機
Java虛擬機(JVM)是Java Virtual Machine的縮寫,它是一個虛構出來的計算機,是通過在實際的計算機上模擬模擬各種計算機功能模擬來實現的。Java虛擬機有自己完善的硬體架構,如處理器、堆棧、寄存器等,還具有相應的指令系統。
1.為什麼要使用Java虛擬機
Java語言的一個非常重要的特點就是與平台的無關性。而使用Java虛擬機是實現這一特點的關鍵。一般的高級語言如果要在不同的平台上運行,至少需要編譯成不同的目標代碼。而引入Java語言虛擬機後,Java語言在不同平台上運行時不需要重新編譯。Java語言使用模式Java虛擬機屏蔽了與具體平台相關的信息,使得Java語言編譯程序只需生成在Java虛擬機上運行的目標代碼(位元組碼),就可以在多種平台上不加修改地運行。Java虛擬機在執行位元組碼時,把位元組碼解釋成具體平台上的機器指令執行。
2.誰需要了解Java虛擬機
Java虛擬機是Java語言底層實現的基礎,對Java語言感興趣的人都應對Java虛擬機有個大概的了解。這有助於理解Java語言的一些性質,也有助於使用Java語言。對於要在特定平台上實現Java虛擬機的軟體人員,Java語言的編譯器作者以及要用硬體晶元實現Java虛擬機的人來說,則必須深刻理解Java虛擬機的規范。另外,如果你想擴展Java語言,或是把其它語言編譯成Java語言的位元組碼,你也需要深入地了解Java虛擬機。
3.Java虛擬機支持的數據類型
Java虛擬機支持Java語言的基本數據類型如下:
byte://1位元組有符號整數的補碼
short://2位元組有符號整數的補碼
int://4位元組有符號整數的補碼
long://8位元組有符號整數的補碼
float://4位元組IEEE754單精度浮點數
double://8位元組IEEE754雙精度浮點數
char://2位元組無符號Unicode字元
幾乎所有的Java類型檢查都是在編譯時完成的。上面列出的原始數據類型的數據在Java執行時不需要用硬體標記。操作這些原始數據類型數據的位元組碼(指令)本身就已經指出了操作數的數據類型,例如iadd、ladd、fadd和dadd指令都是把兩個數相加,其操作數類型別是int、long、float和double。虛擬機沒有給boolean(布爾)類型設置單獨的指令。boolean型的數據是由integer指令,包括integer返回來處理的。boolean型的數組則是用byte數組來處理的。虛擬機使用IEEE754格式的浮點數。不支持IEEE格式的較舊的計算機,在運行Java數值計算程序時,可能會非常慢。
虛擬機支持的其它數據類型包括:
object//對一個Javaobject(對象)的4位元組引用
returnAddress//4位元組,用於jsr/ret/jsr-w/ret-w指令
注:Java數組被當作object處理。
虛擬機的規范對於object內部的結構沒有任何特殊的要求。在Sun公司的實現中,對object的引用是一個句柄,其中包含一對指針:一個指針指向該object的方法表,另一個指向該object的數據。用Java虛擬機的位元組碼表示的程序應該遵守類型規定。Java虛擬機的實現應拒絕執行違反了類型規定的位元組碼程序。Java虛擬機由於位元組碼定義的限制似乎只能運行於32位地址空間的機器上。但是可以創建一個Java虛擬機,它自動地把位元組碼轉換成64位的形式。從Java虛擬機支持的數據類型可以看出,Java對數據類型的內部格式進行了嚴格規定,這樣使得各種Java虛擬機的實現對數據的解釋是相同的,從而保證了Java的與平台無關性和可
移植性。
二、Java虛擬機體系結構
Java虛擬機由五個部分組成:一組指令集、一組寄存器、一個棧、一個無用單元收集堆(Garbage-collected-heap)、一個方法區域。這五部分是Java虛擬機的邏輯成份,不依賴任何實現技術或組織方式,但它們的功能必須在真實機器上以某種方式實現。
1.Java指令集
Java虛擬機支持大約248個位元組碼。每個位元組碼執行一種基本的CPU運算,例如,把一個整數加到寄存器,子程序轉移等。Java指令集相當於Java程序的匯編語言。
Java指令集中的指令包含一個單位元組的操作符,用於指定要執行的操作,還有0個或多個操作數,提供操作所需的參數或數據。許多指令沒有操作數,僅由一個單位元組的操作符構成。
虛擬機的內層循環的執行過程如下:
do{
取一個操作符位元組;
根據操作符的值執行一個動作;
}while(程序未結束)
由於指令系統的簡單性,使得虛擬機執行的過程十分簡單,從而有利於提高執行的效率。指令中操作數的數量和大小是由操作符決定的。如果操作數比一個位元組大,那麼它存儲的順序是高位位元組優先。例如,一個16位的參數存放時佔用兩個位元組,其值為:
第一個位元組*256+第二個位元組位元組碼指令流一般只是位元組對齊的。指令tabltch和lookup是例外,在這兩條指令內部要求強制的4位元組邊界對齊。
2.寄存器
Java虛擬機的寄存器用於保存機器的運行狀態,與微處理器中的某些專用寄存器類似。
Java虛擬機的寄存器有四種:
pc:Java程序計數器。
optop:指向操作數棧頂端的指針。
frame:指向當前執行方法的執行環境的指針。
vars:指向當前執行方法的局部變數區第一個變數的指針。
Java虛擬機
Java虛擬機是棧式的,它不定義或使用寄存器來傳遞或接受參數,其目的是為了保證指令集的簡潔性和實現時的高效性(特別是對於寄存器數目不多的處理器)。
所有寄存器都是32位的。
3.棧
Java虛擬機的棧有三個區域:局部變數區、運行環境區、操作數區。
(1)局部變數區
每個Java方法使用一個固定大小的局部變數集。它們按照與vars寄存器的字偏移量來定址。局部變數都是32位的。長整數和雙精度浮點數占據了兩個局部變數的空間,卻按照第一個局部變數的索引來定址。(例如,一個具有索引n的局部變數,如果是一個雙精度浮點數,那麼它實際占據了索引n和n+1所代表的存儲空間。)虛擬機規范並不要求在局部變數中的64位的值是64位對齊的。虛擬機提供了把局部變數中的值裝載到操作數棧的指令,也提供了把操作數棧中的值寫入局部變數的指令。
(2)運行環境區
在運行環境中包含的信息用於動態鏈接,正常的方法返回以及異常傳播。
·動態鏈接
運行環境包括對指向當前類和當前方法的解釋器符號表的指針,用於支持方法代碼的動態鏈接。方法的class文件代碼在引用要調用的方法和要訪問的變數時使用符號。動態鏈接把符號形式的方法調用翻譯成實際方法調用,裝載必要的類以解釋還沒有定義的符號,並把變數訪問翻譯成與這些變數運行時的存儲結構相應的偏移地址。動態鏈接方法和變數使得方法中使用的其它類的變化不會影響到本程序的代碼。
·正常的方法返回
如果當前方法正常地結束了,在執行了一條具有正確類型的返回指令時,調用的方法會得到一個返回值。執行環境在正常返回的情況下用於恢復調用者的寄存器,並把調用者的程序計數器增加一個恰當的數值,以跳過已執行過的方法調用指令,然後在調用者的執行環境中繼續執行下去。
·異常和錯誤傳播
異常情況在Java中被稱作Error(錯誤)或Exception(異常),是Throwable類的子類,在程序中的原因是:①動態鏈接錯,如無法找到所需的class文件。②運行時錯,如對一個空指針的引用
·程序使用了throw語句。
當異常發生時,Java虛擬機採取如下措施:
·檢查與當前方法相聯系的catch子句表。每個catch子句包含其有效指令范圍,能夠處理的異常類型,以及處理異常的代碼塊地址。
·與異常相匹配的catch子句應該符合下面的條件:造成異常的指令在其指令范圍之內,發生的異常類型是其能處理的異常類型的子類型。如果找到了匹配的catch子句,那麼系統轉移到指定的異常處理塊處執行;如果沒有找到異常處理塊,重復尋找匹配的catch子句的過程,直到當前方法的所有嵌套的catch子句都被檢查過。
·由於虛擬機從第一個匹配的catch子句處繼續執行,所以catch子句表中的順序是很重要的。因為Java代碼是結構化的,因此總可以把某個方法的所有的異常處理器都按序排列到一個表中,對任意可能的程序計數器的值,都可以用線性的順序找到合適的異常處理塊,以處理在該程序計數器值下發生的異常情況。
·如果找不到匹配的catch子句,那麼當前方法得到一個"未截獲異常"的結果並返回到當前方法的調用者,好像異常剛剛在其調用者中發生一樣。如果在調用者中仍然沒有找到相應的異常處理塊,那麼這種錯誤傳播將被繼續下去。如果錯誤被傳播到最頂層,那麼系統將調用一個預設的異常處理塊。
(3)操作數棧區 機器指令只從操作數棧中取操作數,對它們進行操作,並把結果返回到棧中。選擇棧結構的原因是:在只有少量寄存器或非通用寄存器的機器(如Intel486)上,也能夠高效地模擬虛擬機的行為。操作數棧是32位的。它用於給方法傳遞參數,並從方法接收結果,也用於支持操作的參數,並保存操作的結果。例如,iadd指令將兩個整數相加。相加的兩個整數應該是操作數棧頂的兩個字。這兩個字是由先前的指令壓進堆棧的。這兩個整數將從堆棧彈出、相加,並把結果壓回到操作數棧中。
每個原始數據類型都有專門的指令對它們進行必須的操作。每個操作數在棧中需要一個存儲位置,除了long和double型,它們需要兩個位置。操作數只能被適用於其類型的操作符所操作。例如,壓入兩個int類型的數,如果把它們當作是一個long類型的數則是非法的。在Sun的虛擬機實現中,這個限制由位元組碼驗證器強制實行。但是,有少數操作(操作符pe和swap),用於對運行時數據區進行操作時是不考慮類型的。
4.無用單元收集堆
Java的堆是一個運行時數據區,類的實例(對象)從中分配空間。Java語言具有無用單元收集能力:它不給程序員顯式釋放對象的能力。Java不規定具體使用的無用單元收集演算法,可以根據系統的需求使用各種各樣的演算法。
5.方法區
方法區與傳統語言中的編譯後代碼或是Unix進程中的正文段類似。它保存方法代碼(編譯後的java代碼)和符號表。在當前的Java實現中,方法代碼不包括在無用單元收集堆中,但計劃在將來的版本中實現。每個類文件包含了一個Java類或一個Java界面的編譯後的代碼。可以說類文件是Java語言的執行代碼文件。為了保證類文件的平台無關性,Java虛擬機規范中對類文件的格式也作了詳細的說明。其具體細節請參考Sun公司的Java虛擬機規范。
10. JAVA編程中「兩個大整數求和」怎麼編寫
將大整數存入字元數組,按位相加。 給你寫一段偽代碼。
String a = "12389839843958394";
String b = "23445655234343";
char ac [] = a.toCharArray();
char bc [] = b.toCharArray();
這里要將數組ac 和bc 倒序排列,因為"123"轉換後為{'1','2','3'} 高位在前,倒序是為了低位在前。這部分代碼自己實現把。
char longc[];
char shortc[];
if (ac.length>=bc.length) {
longc=ac;
shortc=bc;
} else {
longc=bc;
shortc=ac;
}
下面做一個for循環,按位相加乘以10的i次方。就像小學學的列豎式子一樣
int sum=0;
for (int i=longc.length;i<longc.length;i++) {
if (i<shortc.length) {
sum+=(longc[i]+shortc[i]-96)*Math.pow(10, i);
} else {
sum+=(longc[i]-48)*Math.pow(10, i);
}
}
其中字元相加的時候減48是將char 轉換成int