第 15 章 Math object

德嘉書業 / 德嘉資訊科技 (www.takka.com.hk) 作者: 伍新華 Email: ng-sun-wah@graduate.hku.hk

15.1 Math property

1.  Math.PI

2.  Math.E

3.  Math.LN10

4.  Math.LN2

5.  Math.LOG10E

6.  Math.LOG2E

7.  Math.SQRT1_2

8.  Math.SQRT2

15.2  Math method

1. Math.abs( )

2. Math.round( )

3. Math.ceil( )

4. Math.floor( )

5. Math.max( )

6. Math.min( )

7.  其他

15.3 Math.random( ) 及隨機數


 

 

 

 

  Math object 是 JavaScript 用來處理一些數學計算, 請先看一些有關數字的資料。

 

Floating-point values:

  JavaScript 的浮點數是使用 e 或 E 為 exponent 的符號, 例如 1.238、5.6e5 (這等於 560000)、4.2e-6 (這等於 0.0000042)。

 

Integers 及進位基數:

  Integers 是整數 (沒有小數位), 預設是十進位 (decimal), 但也可以是十六進位 (hexadecimal)。若是十六進位, 要在數字前加上 0x 或 0X, 例如 0x6A (即十進位的 106), 以下是使用十六進位的例子。

<script>
a =
0x100
b =
0x4A
document.write( a * b )
</script>

  這會顯示 18944, 即是十六進位的 4A00。

 

toString( ) 及進位基數:

  在第 8.4-10 的一段說過 toString( ) 的用途, 這功能是用來將數字變為文字格式, 在這轉變過程, 我們可以指定得出來的數值使用哪一個進位基數 (radix), 預設是十進位, 我們可指定二、八或十六進位, 使用的是以下語法: value.toString(radix) , 請看以下例子:

<script>
x =
100
a = x.toString(2)
b = x.toString(10)
c = x.toString(16)
document.write( a +"<br>" + b + "<br>" + c )
</script>

  這 script 會顯示以下三個數字:

1100100    ( 100 變為二進位來顯示)
100      ( 100 以十進位來顯示)
64       ( 100 變為十六進位來顯示)

 

 

15.1 Math property

  Math 是一個高層的物件, 不隸屬於其他物件, 其下則有一列的 property 及 method, 可用作數學運算, 使用時有這格式: Math.propertyMath.method( ), 這一節是說Math 的 property。

 

1. Math.PI

  這是圓周率, 約為 3.1416, 例如:

<script>
x =Math.PI * 10
document.write( "1
0 cm直徑的圓形, 圓周是: " + x + " cm. " )
</script>

  這會顯示 x 的數值, 約是: 31.4159

 

2. Math.E

  這是 Euler's constant, 約為 2.7182, 例如:

<script>
x = Math.E
document.write( x )
</script>

  這會顯示 x 的數值, 約是: 2.7182

 

3. Math.LN10

  這是 10 的 natural logarithm, 約為 2.3026, 例如:

<script>
x = Math.LN10
document.write( x )
</script>

  這會顯示 x 的數值, 約是: 2.3026

 

4. Math.LN2

  這是 2 的 natural logarithm, 約為 0.6931, 例如:

<script>
x = Math.LN2
document.write( x )
</script>

  這會顯示 x 的數值, 約是: 0.6931

 

5. Math.LOG10E

  這是 E 的 base 10 logarithm, 約為 0.4343, 例如:

<script>
x = Math.LOG10E
document.write( x )
</script>

  這會顯示 x 的數值, 約是: 0.4343

 

6. Math.LOG2E

  這是 E 的 base 2 logarithm, 約為 1.4427, 例如:

<script>
x = Math.LOG2E
document.write( x )
</script>

  這會顯示 x 的數值, 約是: 1.4427

 

7. Math.SQRT1_2

  這是 1/2 的 square root, 約為 0.7071, 例如:

<script>
x = Math.SQRT1_2
document.write( x )
</script>

  這會顯示 x 的數值, 約是: 0.7071

 

8. Math.SQRT2

  這是 2 的 square root, 約為 1.4142. 例如:

<script>
x = Math.SQRT2
document.write( x )
</script>

  這會顯示 x 的數值, 約是: 1.4142

 


15.2 Math method

 

1. Math.abs( )

  這是傳回一個數字的絕對值 (absolute value), 請看這例子:

<script>
x =
10 * -3
y = Math.abs ( x )
document.write("
The absolute value of x is " + y )
</script>

  x -30 , abs(x) 除去負值, 所以 y 30

 

2. Math.round( )

  以四捨五入的方式將數字變為整數, 請看以下例子:

<script>
document.write( Math.round(
3.49) )
document.write( Math.round(-
3.49) )
document.write( Math.round(
3.51) )
document.write( Math.round(-
3.51) )
</script>

  假若有一些數值, 我們只要某一個數目的小數位, 例如兩個小數位, 可以將這數值先 x100, 經過 Math.round( ) 後, 再 /100, 例如 Math.PI*10 是 31.4159265359, 若只要兩個小數位, 可使用這設定:

<script>
function twoDecimal(a)
{ return (Math.round(a *
100) ) /100 
}
x=Math.PI *
10
document.write( "
10 cm直徑, 圓周是: " + twoDecimal(x) + " cm。" )
</script>

  這例子的 twoDecimal(a) 是專門擷取兩個小數位的 function, 任何小數的數字, 只要用 argument 的方法將數字送給這 function, 例如 twoDecimal(2.3472), 就會傳回  2.35。

  若要三個小數位, 就是: (Math.round( a * 1000) ) /1000。

 

3. Math.ceil( )

  這是將有小數位的數字向上調整為整數, 例如 1.23 變為 2, 45.37 變為 46, 負數也是向上調整, 例如 -1.23 變為 -1 , -45.37 變為 -45, 請看以下例子:

<script>
y = Math.ceil(
34.12)
document.write(y *
5)
</script>

  假若有很多數字要轉變, 可用一個專用的 function 來進行, 例如以下的 getCeil(x) :

<script>
function getCeil(x)
 { return Math.ceil(x) }

a=
2.5
document.write( getCeil(a *
3) + " <br> " )
document.write( getCeil(a * -
5) )
</script>

 

4. Math.floor( )

  這是將有小數位的數字向下調整為整數, 例如 1.23 變為 1, 45.37 變為 45, 負數也是向下調整, 例如 -1.23 變為 -2 , -45.37 變為 -46, 請看以下例子: 

<script>
function getFloor(x)
 { return Math.floor(x) }
a=
2.5
document.write( getFloor(a *
3) + " <br> " )
document.write( getFloor(a * -
5) )
</script>

 

5. Math.max( )

  這比較兩個數值, 然後傳回較大的一個, 例如:

<script>
x =
10
y =
20
alert( Math.max( x, y ) )
</script>

  以上的對話盒會顯示 y 的數值, 即是 20

 

6. Math.min( )

  這與 Math.max( ) 相反, 會傳回兩個數值中, 數值較細的一個。

 

7. 其他

  Math 還有以下十多個其他與數學有關的 method, 我們較少用, 所以筆者也不詳細解說。

 

Math.acos( ) 傳回一個數值的 arccosine (in radians)。
Math.asin( ) 傳回一個數值的 arcsine (in radians)。
Math.atan( ) 傳回一個數值的 arctangent (in radians)。
Math.cos( )  傳回一個數值 cosine。
Math.log( ) 傳回一個數值的 natural logarithm (base E)。
Math.pow( ) 傳回一個數值的 exponent power。
Math.sin( )  傳回一個數值的 sine。
Math.sqrt( ) 傳回一個數值的 square root。
Math.tan( )  傳回一個數值的 tangent。

 

 


15.3 Math.random( ) 及隨機數

  在 Math object 中, random( ) 是最有用的工具, 所以筆者以較多篇幅來說明。Math.random( ) 是傳回一個由 0 至 1 之間有 17 個小數位的隨機數 (random number), 這數值是一個 pseudo-random number, 不是真的由程式產生出來的隨機數, 而是利用當時的時間 (current time) 再經某個運算方式產生出來。

  請你試試以下的 script, 在按鈕上按一下, 就會有對話盒顯示一個數字。

練習-119 原始的隨機數

1. 請用瀏覽器開啟示範磁碟中的 random1.htm, 這檔案有以下內容:

<html> <body bgcolor=oldlace>
<form>
<input type=button value="
Give me a random number"
  onClick="alert(Math.random( ) )">
</form>
</body> </html>

2. 網頁開啟後, 會有一個按鈕, 請你按一下, 會有 alert 對話盒顯示一個數字, 例如:  0.3575008833419737 , 再按一下, 又會有另一個數字。

 

 

練習-120 產生由 1 至 100 的隨機數

  上個例子產生的隨機數是 16 位小數的數字, 在實際使用時, 我們通常都要作一些修改, 在這例子, 我們要從這數字變為產生 1 至 100 的隨機數, 方式要將原始數字乘以 100, 再捨去隨後的小數位數字。

1. 請用瀏覽器開啟示範磁碟中的 random2.htm, 這檔案有以下內容:

<html> <body bgcolor=aliceblue>
<form>
<input type=button value="
Give me a random number"
  onClick="ranNum( )">
</form>
<script>
function ranNum( )
{ x=Math.random( )
  x=Math.floor(x *
100 + 1)
  alert(x)
}
</script> </body> </html>

2. 網頁開啟後, 請你試試按鈕產生出來的隨機數

 

1. 這處用 Math.random( ) 來產生隨機數, 這隨機數用 x 來代表。

2. 跟著使用 *100 來將這隨機數的小數點向右移兩個位, 並用 Math.floor( ) 刪去隨後的小數位, 得出 00 至 99 的隨機數, 若要變為 1 至 100 的隨機數, 可將數字加 1。

  上述例子用移動小數點的方法, 可產生 1 至 10n 的隨機數, 最大的隨機數是 10 的整倍數, 若要產生這範圍外的隨機數, 可使用 練習-59 的方法設定一個檢查, 若產生的隨機數不在這範圍就不要, 重新再產生。另一個正統的方法是使用 modulus 的功能, modulus 是餘數, 請看 7.2 的一節, 例如要產生 1 至 13 的隨機數, 可使用以下練習的方法。

 

練習-121 產生由 1 至 13 的隨機數

  這網頁有一個按鈕, 你按一下, 就會有 alert 對話盒顯示一個 1 至 13 範圍的隨機數。

1. 請用瀏覽器開啟示範磁碟中的 random3.htm, 這檔案有以下內容:

<html> <body bgcolor=seagreen>
<form> <input type=button value="
Give me a random number"
  onClick="ranNum( )">
</form>
<script>
function ranNum( )
{ x=Math.random( )
  x=Math.floor(x *
329 / 7 )
  x = x %
13 + 1
  alert(x)
}
</script> </body> </html>

2. 網頁開啟後, 請你試試按鈕產生出來的隨機數, 看是否在 1 至 13 的範圍。

  在這例子, 筆者將 Math.random( ) 產生出來的隨機數乘以 329 再除以 7, 這兩個數字都是隨意的, 沒有特別原因, 只是用來增加數字的隨機性。跟著的 x=x%13 是將 x 除以 13, 然後取其餘數, 這會得出 0 至 12 的隨機數, 將數字加 1 就變為 1 至 13 的範圍。

 

練習-122 1 至 13 的隨機數的應用

  在上個練習, 你看過如何產生 1 至 13 範圍的隨機數, 在這練習, 筆者以一個很簡單的紙牌鬥大遊戲, 來示範這隨機數的使用, 在 7.5 的一節有一個大小遊戲, 也是使用類似方式。

  這練習的遊戲有以下 algorithm:

a) 這遊戲有 13 張紙牌的陣列。

b) 網頁開啟後, 有兩個圖片位置, 顯示兩張紙牌的底部, 一張是電腦的牌, 一張是你的牌。

c) 圖片位置下有一個按鈕, 上有 "向你發牌" 的文字, 按一下, 就會翻開你的牌, 按鈕上的文字變為 "向電腦發牌", 按一下, 就會翻開電腦的牌。

d) 翻牌後, 這遊戲會看哪一張牌大, 然後以 alert 對話盒顯示 "電腦嬴了" 或 "你嬴了" 的訊息, 按 [確定] 就會清除兩幅圖片及回到前面的程序 (b) 。

e) 網頁中另有一個 [統計] 的按鈕, 按一下, 就會顯示你嬴的次數及輸的次數。

 

1. 請用瀏覽器開啟示範磁碟中的 random4.htm, 這檔案有以下內容:

<html> <body bgcolor=seashell>

<center> <table width=60%>    //這部份產生兩幅圖片的位置
<tr> <td width=
40% align=center>
<img src=
null.gif name=pos1 width=75 height=100> </td>
<td width=
40% align=center>

<img src=null.gif name=pos2 width=75 height=100> </td> </tr>
<tr> <td align=center> 你的牌 </td> <td align=center> 電腦的牌
</td> </tr> </table> <br>

<form name=fm>    //這部份產生兩個按鈕
<input type=button name=bn1 value="
向你發牌
  onClick="deliver( )"> &nbsp;&nbsp;&nbsp;
<input type=button name=bn2 value="
統計" onClick="checkIt( )">
</form>

<script>

       //這將 13 張紙牌圖案排成一個名為 suit 的陣列
suit=new Array("
h01.gif","h02.gif","h03.gif","h04.gif","h05.gif","h06.gif",
  "
h07.gif","h08.gif","h09.gif","h10.gif","h11.gif","h12.gif","h13.gif")

flag=0     // 將 3 個變數的初始值設為 0
youWin=
0   
// youWin 是你嬴的次數。
compWin=
0
  // compWin 電腦嬴的次數。

function deliver( )      // youcomp 分別代表配給你及電腦的隨機數。
{ if (flag==
0)
   { you=Math.random( )
     you=parseInt(you *
1000 )
      //這看下方說明1
     you=you%
13
     document.pos1.src=suit[you]
     document.fm.bn1.value="
向電腦發牌"
     flag=
1
   
}
 else { 
do 
      
{ comp=Math.random( )
        comp=parseInt(comp *
1000 )   
//這看下方說明2
        comp=comp%
13 }
      while (comp==you)
     document.pos2.src=suit[comp]
     document.fm.bn1.value="
向你發牌"
     flag=
0
     setTimeout("showResult( )",
500)
   }
}

function showResult( )     //這顯示在一個回合中誰嬴了, 
{ if(you==
0)  you=13   
//  及記下雙方各勝出的次數。
   if(comp==0)  comp=
13
   alert( (you > comp? "
今次你嬴了" : "今次電腦嬴了") )
   document.pos1.src="
null.gif"
   document.pos2.src="
null.gif"
   if (you > comp) youWin = youWin+
1
   if (comp > you) compWin = compWin+
1

function checkIt( )        //這顯示雙方各勝出的次數。
{ if(youWin==
0 && compWin==0)
    { alert("
遊戲還未開始!") }
 else  { if(youWin==compWin
        { alert("
你和電腦各嬴 " + youWin + " 次, 打平手。") }
      else { alert("
你嬴了 " + youWin + " 次, \n \n"
            + "
電腦嬴了 " + compWin + " 次, \n \n"
                     + (youWin > compWin?"
總數你嬴了。":"總數電腦嬴了。") )
         }
            }    
}
</script>

</body> </html>

2. 網頁開啟後, 請你試試這遊戲

 

  說明 1: 這例子利用 flag==0 或  flag==1 來決定向誰派牌, 首先是 flag==0, 即是向你派牌, 方式是使用 Math.random( ) 得出一個隨機數, 然後乘 1000 及利用 parseInt( ) 變為整數, 再利用 %13 來得出一個 0 至 12 範圍的隨機數, 並用 you 這變數來代表。

  得出這變數後, 就可在 document.pos1 這位置來顯示在 suit 陣列中有關的圖片, 最後將 flag 轉為 1。

 

  說明 2: 第二次按下有關的按鈕, 因 flag==1, 因此這處的隨機數是給電腦的, 並用 comp 這變數來代表, 留意今次有 while(comp==you) 的迴圈, 若今次的變數與 you 的相同, 就重新再求另一個變數。

  得出這變數後, 就可在 document.pos2 這位置來顯示在 suit 陣列中有關的圖片, 再將 flag 轉回 0, 最後用 showResult( ) checkIt( ) 來顯示誰嬴了及統計各勝出的次數。

  在 showResult( ) 這 function 內, 留意有 if(you==0) you=13 , you==0 是開出 ace, 這是最大的牌, 所以要轉為 13, 否則就會是最細的牌。


( 第 15 章完 )