Java Primitive Datatype

โดย เม้ง

1. เกริ่นนำ
บทความนี้เราจะมาพูดกันถึงชนิดของตัวแปร (variable type) ที่จาวามีให้ใช้ได้ทันที ส่วนนี้จะเป็นส่วนที่สำคัญมากเพราะจะเป็นพื้นฐานให้กับการเขียนโปรแกรมในทุกภาษา โดยเฉพาะผู้ที่เขียนโปรแกรมที่ต้องมีการเกี่ยวข้องกับคำนวญทางคณิตศาสตร์ ถ้าคุณผู้อ่านไม่ทำความเข้าใจกับการใช้ตัวแปร (variable) เหล่านี้ล่ะก็จะทำให้เกิดความผิดพลาดในตัวโปรแกรมและจะเป็นบั๊ก (bug) ที่หาค่อนข้างยาก ในบทความนี้ผู้เขียนพยายามเน้นในเรื่องของ complement และตัวแปรที่เป็นตัวเลขเสียส่วนมากเพราะคิดว่าคุณผู้อ่านบางท่านคงจะสนใจหรือไม่เคยรู้ในส่วนนี้มาก่อน ผู้เขียนหวังว่าคงจะเกิดประโยชน์แก่คุณผู้อ่านที่จะเอาความรู้นี้ไปใช้ในการเขียนโปรแกรมที่ต้องการใช้การคำนวณเพื่อให้เกิดความผิดพลาดน้อยที่สุด

2. วัตถุประสงค์
เพื่อที่จะให้คุณผู้อ่านได้รู้จักและคุ้นเคยกับ
2.1 การประกาศ (declaration) และการตั้งค่า (assignment) และการตั้งค่าเริ่มต้น (initialization) ของตัวแปร
2.2 การตั้งชื่อตัวแปร
2.3 ชนิดของตัวแปรต่างๆที่จาวามีให้
2.4 ค่าน้อยสุดและค่ามากสุดของตัวแปรแต่ละชนิดตลอดจนถึงการใช้ตัวแปรเหล่านั้นและข้อควรระวัง
2.5 การทำ one's และ two's Complement และความหมายของทั้งสอง Complements
2.6 การใช้ Literal Constant
2.7 การทำ Variable Type Casting
2.8 การใช้ final identifier

3. การประกาศ การตั้งค่า และการตั้งค่าเริ่มต้นของตัวแปร
การประกาศตัวแปร (declaration) ในจาวาให้ทำดังนี้

type varname1, varname2, ... ;

ในการประกาศตัวแปรนั้นประกอบไปด้วยสองส่วนใหญ่ๆคือ ชนิดของตัวแปร (type) และชื่อของตัวแปร (varname) โปรดสังเกตว่าที่ท้ายของบรรทัดนั้นจบด้วยเครื่องหมาย ";" ในจาวานั้นทุกบรรทัดที่เป็นการประกาศตัวแปรหรือฟังก์ชันนั้นจะต้องจบด้วยเครื่องหมายนี้ เราสามารถประกาศตัวแปรหลาย ๆ ตัวพร้อม ๆ กันได้ภายในบรรทัดเดียวดังตัวอย่างข้างบน ตัวแปรที่อยู่ในบรรทัดนั้นจะเป็นชนิดเดียวกันทั้งหมด

ในจาวานั้นหลังจากที่คุณผู้อ่านประกาศตัวแปรแล้วจาวาจะใส่ค่าเริ่มต้น (initialize) ให้ตัวแปรเหล่านั้นทันที เพราะฉะนั้นคุณผู้อ่านก็สามารถรู้ได้ทันทีว่าตัวแปรที่คุณผู้อ่านประกาศไว้นั้นมีค่าเท่าใหร่ แต่คุณผู้อ่านไม่ควรจะเชื่อค่าเหล่านั้นเพราะค่าเหล่านี้อาจจะถูกเปลี่ยนในอนาคตก็ได้ผู้เขียนจึงขอเสนอว่าให้คุณผู้อ่านตั้งค่าเริ่มต้นด้วยตนเองเสมอ

ถ้าคุณผู้อ่านต้องการทั้งประกาศและตั้งค่าเริ่มต้นด้วยในบรรทัดเดียวกันก็สามารถทำได้ดังนี้

type varname1=varvalue1, varname2=varvalue2, ... ;

การตั้งค่าของตัวแปร (assignment) นั้นก็คือการก๊อปปี้ค่าใส่เข้าไปในตัวแปรนั้นนั่นเอง ตัวแปรที่จะถูกตั้งค่านั้นจะต้องเป็นตัวแปรที่ถูกประกาศมาแล้วและจะต้องอยู่ทางซ้ายของเครื่องหมายเท่ากับ (=) และค่าที่จะใส่เข้าไปในตัวแปรนั้นต้องอยู่ทางขวาของเครื่องหมายเท่ากับ

varname=varvalue;

นอกจากจะตั้งค่าของตัวแปรด้วย value แล้วคุณยังสามารถตั้งค่าด้วยตัวแปรอื่นด้วย เช่น

varname1=varname2=varname3=varvalue1;

ในบรรทัดข้างบนนี้จาวาจะก๊อปปี้ค่าจากทางขวาสุดไปทางซ้ายสุด เพราะฉะนั้นค่าของ varname1varname2 และ varname3 จะมีค่าเท่ากันซึ่งเท่ากับ varvalue1

ข้อกำหนดของการตั้งค่าตัวแปรนั้นตัวแปรและค่าที่จะตั้งนั้นต้องเป็นชนิดเดียวกัน ยกตัวอย่างเช่น a=20, ตัวแปร a นั้นต้องเป็นตัวแปรชนิด integer มีข้อยกเว้นบางประการที่ตัวแปรและค่าที่จะตั้งอาจไม่ต้องเป็นชนิดเดียวกันแต่จะยกไปพูดในเรื่องของการ casting ส่วนทางด้านซ้ายของเครื่องหมายเท่ากับจะต้องเป็นตัวแปรที่สามารถใส่ค่าได้เท่านั้น ถ้าคุณลองคอมไพล์ไฟล์ที่มีบรรทัด 50=50; จาวาคอมไพเลอร์จะฟ้องว่ามี error

4. การตั้งชื่อของตัวแปร
4.1. ชื่อตัวแปรนั้นต้องเป็นขึ้นต้นด้วยตัวอักษร (a-z,A-Z) หลังจากนั้นจะเป็นตัวอักษรหรือตัวเลขก็ได้
4.2. ชื่อตัวแปรนั้นต้องไม่ซ้ำกับ keyword ของจาวา ยกตัวอย่างเช่น int หรือ public ไม่สามารถใช้เป็นชื่อของตัวแปรได้ แต่ int1 หรือ publicity เป็นชื่อที่ถูกกฎ
4.3. เครื่องหมายบางชนิดที่ไม่มีความหมายอย่างอื่นในจาวาสามารถใช้เป็นส่วนหนึ่งของชื่อตัวแปรได้ อย่างเช่น a_and_b เป็นชื่อที่ถูกกฎแต่ a-and-b ไม่ใช่ เครื่องหมาย "-" จะถูกแปลว่าเป็นการลบ

5. ตัวแปรที่คุณผู้อ่านควรจะรู้จัก
ตัวแปรที่คุณผู้อ่านควรจะทำความรู้จักไว้มีดังนี้

ตารางที่ 1 ชนิดและขนาดของตัวแปรต่าง ๆ

VARIABLE TYPE DESCRIPTION SIZE(bits) MAX VALUE MIN VALUE
byte byte-length integer 8-bit
two's complement
(2^7)-1
=127
-1*((2^7)-1)
=-127
short small integer 16-bit
two's complement
(2^15)-1
=32,767
-1*((2^15)-1)
=-32,767
int integer 32-bit
two's complement
(2^31)-1
=2,147,483,647
-1*((2^31)-1)
=-2,147,483,647
long long integer 64-bit
two's complement
(2^63)-1
=9,223,372,036,854,775,807
-1*((2^63)-1)
=-9,223,372,036,854,775,807
float single precision floating point 32-bit IEEE 754 3.4028235*10^38 หรือ
3.4028235E38
-3.4028235*10^38 หรือ
-3.4028235E38
double double precision floating point 64-bit IEEE 754 1.7976931348623157*10^308
หรือ 1.7976931348623157E308
-1.7976931348623157*10^308
หรือ -1.7976931348623157E308
char a single character 16-bit Unicode Character N/A N/A
boolean boolean true or false N/A N/A
String string object variable N/A N/A
literal constant literal constant variable N/A N/A
+++ ในตารางนี้ สมมติให้เครื่องหมาย * แทนการคูณ เครื่องหมาย ^ แทนการยกกำลัง และ N/A แทน Non-Applicable 

จริงๆแล้วเรื่อง complement นี้ผู้ที่เขียนโปรแกรมไม่จำเป็นต้องรู้ในรายละเอียดก็ได้ แต่ผู้เขียนเองอยากจะเขียนไว้ให้เป็นเกร็ดความรู้แด่คุณผู้อ่าน ถ้าคุณผู้อ่านท่านใดที่ทราบเกี่ยวกับ complement แล้วหรือไม่สนใจในรายละเอียดก็สามารถข้ามหัวข้อที่ 6 และ 7 ไปได้โดยไม่ขาดความต่อเนื่องนะครับ

6. Complements
Complement ก็คือ ส่วนที่ทำให้ complete หรือที่เรียกว่าส่วนเติมเต็มนั่นเอง ถ้าเรามองว่ามีน้ำอยู่ในแก้วใบหนึ่ง complement ของน้ำในแก้วใบนั้นก็คือปริมาตรของน้ำที่เติมเข้าไปในแก้วเพื่อที่จะให้น้ำในแก้วนั้นเต็มพอดี คุณคงจะสังเกตเห็นว่า complement นั้นขึ้นอยู่กับสองปัจจัยคือปริมาณของน้ำที่มีอยู่และปริมาตรของแก้ว จากความจริงข้างบนเราจะสามารถแปลให้เป็นสมการคณิตศาสตร์ได้ดังนี้

ส่วนเติมเต็มของน้ำในแก้ว = ปริมาตรของแก้ว - ปริมาณน้ำที่มีอยู่ในแก้วก่อนแล้ว

ทีนี้เราก็จะมาเปรียบเทียบตัวอย่างในเรื่องของน้ำข้างต้นให้เข้ากับเรื่องของตัวเลขฐานสองของเรานะครับ
ถ้าเรามีเลขฐานสองขนาด N-bits ที่มีค่าเท่ากับ X อยู่ตัวหนึ่ง ปริมาตรของแก้วนั้นเปรียบได้กับตัวเลขฐานสองที่มีค่ามากที่สุดที่สามารถใส่เข้าไป ใน N-bit นั้นได้ ซึ่งตัวเลขนั้นก็คือ (2^N)-1 (หรือ 2 ยกกำลัง N ลบ 1) ปริมาณน้ำที่มีอยู่ในแก้วก่อนแล้วเปรียบได้กับค่า X เพราะฉะนั้น

complement = (2^N)-1 - X

ข้างบนนี้คือคำจำกัดความอย่างง่ายๆของ one's complement เราลองมายกตัวอย่างเล็ก ๆ กันดีกว่านะครับ

ยกตัวอย่างตัวเลข 3-bit 0112 หรือ 3 ค่าที่มากที่สุดที่จะใส่เข้าไปในเลข 3-bit ได้นั้นก็คือ (2^3)-1=8-1=7=1112 (เลขสองที่ห้อยอยู่ท้ายตัวเลขนั้นแสดงว่าตัวเลขที่อยู่ข้างหน้ามันเป็นเลขฐานสอง ถ้าไม่มีเครื่องหมายนี้หมายความว่าเป็นเลขฐานสิบ) คุณจะสังเกตเห็นว่าค่ามากสุดที่จะใส่ เข้าไปในตัวเลข N-bit นั้นก็คือ 111....112 เสมอ แต่จำนวนเลขหนึ่งที่มีอยู่ในนั้นก็คือ N ตัว คุณควรจะพิสูจน์ดูด้วยตนเอง

one's complement of a 3-bit number 112 = 1112-0112 = 1002

คุณจะสังเกตเห็นว่า one's complement นั้นก็คือการกลับตัวเลขจากศูนย์เป็นหนึ่งและจากหนึ่งเป็นศูนย์นั่นเองแต่ว่าคุณต้องเติมเลขศูนย์ข้าง หน้าของตัวเลขที่จะทำ one's complement ให้เต็มจำนวน bit ที่ต้องการเสียก่อน จากตัวอย่างข้างต้นเราต้องเติมศูนย์เข้าไปหนึ่งตัวเพื่อให้ 112 กลายเป็นเลข 3-bit

ทีนี้เราก็จะมาคุยกันถึง two's complement กันบ้างล่ะ two's complement ใกล้เคียงกับ one'c complement มากเพียงแต่เพิ่มค่ามากสุดขึ้นมาอีก 1 เพราะฉะนั้นแทนที่ค่ามากสุดจะเป็น (2^N)-1 หรือ 111....11 ที่มีเลขหนึ่งเท่ากับ N ตัว ก็จะเปลี่ยนเป็น 2^N หรือ 100....00 ที่ มีศูนย์เท่ากับ N ตัว คุณผู้อ่านคงจะสังเกตเห็นว่าจำนวน bit ของค่ามากสุดในกรณีนี้มากกว่า N ไป 1-bit ถ้าเราเอามาเขียนเป็นสมการก็จะได้ว่า

two's complement = one's complement + 1
two's complement = (2^N) - X

ถ้า X คือค่าที่จะทำ complement และ N คือจำนวน bit ที่สนใจ

คุณคงจะสังเกตเห็นได้ว่าการทำ two's complement ที่ง่ายที่สุดก็คือการทำ one's complement (กลับศูนย์เป็นหนึ่งและหนึ่งเป็นศูนย์) แล้วจึงบวกหนึ่งเข้าไป ในบางกรณีหลังจากคุณทำ two's complement แล้วอาจจะได้่ตัวเลขที่มีจำนวน bit เท่ากับ N+1 แต่เราจะยังคงสนใจแค่ N-bit เพราะฉะนั้นเราจะตัด bit ที่เพิ่มขึ้นมาออก อีกอย่างหนึ่งที่คุณผู้อ่านควรจะรู้เกี่ยวกับ complement ก็คือถ้าเรามีเลขฐานสองอยู่ตัวหนึ่งแล้วเราทำ complement สองครั้ง เราจะได้ตัวเลขตัวเดิมกลับมา ลองพิสูจน์ด้วยตนเองดูนะครับ

7. Complement มีไว้เพื่อใช้ทำอะไรใครรู้บ้าง
ใครรู้บ้างเอ่ยว่าเราจะเขียนตัวเลขที่เป็นค่าลบในรูปของเลขฐานสองอย่างไร บทบาทหนึ่งของ Complement ก็คือเรื่องนี้แหละครับ ถ้าเรามีตัวเลขฐานสอง N-bit แต่เราไม่สนใจในเรื่องของเครื่องหมายและสมมติให้เลขตัวนั้นเป็นค่าบวกอย่างเดียว ค่าที่มากที่สุดที่เราจะใส่เข้าไปใน N-bit นั้นได้ก็คือ (2^N)-1 ใช่ใหมครับ แต่ถ้าเราจะให้ N-bit นั้นใส่ได้ทั้งค่าบวกและค่าลบล่ะ อ่าฮ่า เราก็แบ่งเอาครึ่งหนึ่งของ (2^N)-1 มาแทนค่าบวก และอีกครึ่งหนึ่งของ (2^N)-1 มาแทนค่าลบสิครับ เรามาลองยกตัวอย่างกันดูดีกว่าครับ สมมติว่ามีตัวเลขฐานสอง ขนาด 4-bit ครึ่งแรกที่เราจะให้เป็นค่าบวกนั้นก็คือ 00002 จนถึง 01112 นับดูแล้วได้ 8 ตัว หมายความว่าตัวเลขศูนย์จนถึงเจ็ดเราจะแทน ด้วย 00002 จนถึง 01112 ตามลำดับ ที่เหลือก็คือ 10002 จนถึง 11112 เราจะใช้แทนค่าลบศูนย์(อย่าเพิ่งตกใจเมื่อผู้เขียนเขียนถึงลบศูนย์นะครับ ให้อ่านไปเรื่อยๆก่อนคุณจะเข้าใจทีหลัง) จนถึงลบเจ็ดครับ ทีนี้เราจะให้เลขฐานสองตัวใหนล่ะที่จะมาแทนค่าลบศูนย์ถึงลบเจ็ด ผู้เขียน หมายความว่าเราจะจับคู่กันอย่างไรล่ะ คุณผู้อ่านก็ คงจะเห็นด้วยว่ามันก็มีได้หลายร้อยวิธี แต่วิธีที่ง่ายที่สุดต่อคอมพิวเตอร์ก็คือการทำ complement การสลับ bit จากศูนย์เป็นหนึ่งและหนึ่งเป็นศูนย์นั้น เป็นเรื่องง่ายมากสำหรับคอมพิวเตอร์ คุณผู้อ่านคงจะเห็นว่าการทำ complement ในกรณีข้างบนนั้นเป็นฟังก์ชันหนึ่งต่อหนึ่งและถ้าเราทำ complement ตัวเลขตัวหนึ่งสองครั้งเราก็จะได้ตัวเลขตัวเดิมกลับมา เพราะฉะนั้น complement นั้นเป็นสิ่งที่ค่อนข้างเหมาะสมสำหรับการนี้ที่สุด

ทีนี้เรามี complement สองชนิดให้เลือก เรามาลองด้วย one's complement กันก่อนนะครับ
ลองให้คำนิยามของค่าลบของเลขฐานสองว่า

ค่าลบของเลขฐานสอง = one's complement ของเลขฐานสองที่เป็นค่าบวก

แล้วเราก็มาดูตัวอย่างกัน ยกตัวอย่างเดียวกับข้างบน

ตารางที่ 2 one's complement ของตัวเลขฐานสอง 4-bit

ฐานสิบ
ฐานสอง ค่าบวก/
ฐานสิบ
ฐานสอง ค่าลบ/
ฐานสิบ(one's complement)
0
0000/0
1111/-0
1
0001/1
1110/-1
2
0010/2
1101/-2
3
0011/3
1100/-3
4
0100/4
1011/-4
5
0101/5
1010/-5
6
0110/6
1001/-6
7
0111/7
1111/-7

ทีนี้ก็ลอง two's complement ครับ

ค่าลบของเลขฐานสอง = two's complement ของเลขฐานสองที่เป็นค่าบวก

ตารางที่ 3 two's complement ของตัวเลขฐานสอง 4-bit

ฐานสิบ
ฐานสอง ค่าบวก/
ฐานสิบ
ฐานสอง ค่าลบ/
ฐานสิบ(two's complement)
0
0000/0
0000/-0
1
0001/1
1111/-1
2
0010/2
1110/-2
3
0011/3
1101/-3
4
0100/4
1100/-4
5
0101/5
1011/-5
6
0110/6
1010/-6
7
0111/7
1001/-7

คุณผู้อ่านสังเกตเห็นความแตกต่างอะไรบางอย่างในสองกรณีข้างบนใหมครับ ในกรณีที่ตัวเลขเท่ากับ 00002 two's complement ของมันคือตัวเดียวกัน (เลขฐานสองของศูนย์และลบศูนย์คือตัวเดียวกัน) เท่ากับ 00002 แต่สำหรับ one's complement นั้นไม่ใช่ เพราะฉะนั้นในความเห็นของผู้เขียนนั้น two's complement ดูจะเหมาะสมมากกว่าในการแทนค่าลบเรามาลองจัดตารางข้างบนนี้ใหม่ให้ดูง่ายขึ้นกันนะครับ

ตารางที่ 4 เลขฐานสองที่ใช้แทนค่าลบโดยใช้ two's complement

เลขฐานสอง
เลขฐานสิบแบบ
ไม่มีเครื่องหมาย
เลขฐานสิบแบบ
มีเครื่องหมาย
0000
0
0
0001
1
1
0010
2
2
0011
3
3
0100
4
4
0101
5
5
0110
6
6
0111
7
7
1000
8
-8
1001
9
-7
1010
10
-6
1011
11
-5
1100
12
-4
1101
13
-3
1110
14
-2
1111
15
-1

จาก 10002 ในตารางข้างบนนี้เป็นกรณีพิเศษ - ค่า two's complement ของ 10002 ก็คือ   10002 ซึ่งก็คือตัวมันเองทีนี้เราจะให้มันเป็นค่า +8 หรือ -8 ดีล่ะครับ เนื่องจากว่าค่าลบที่เหลือในตารางนั้นขึ้นต้นด้วยเลข 1 เพราะฉะนั้นจะเป็นการดีที่ให้ 10002 แทนค่า -8 เพราะฉะนั้นเราจึงได้บทสรุปแล้วว่าถ้า bit แรกหรือ most significant bit (msb) เป็นค่า 1 เราก็รู้ได้เลยว่าเลขฐานสองนั้นเป็นค่าลบ เพราะฉะนั้น bit นี้จึงถูกเรียกว่า sign bit และถ้าเราพูดถึงตัวเลข N-bit แบบมีเครื่องหมาย (signed) ค่ามากสุดที่เราจะใส่เข้าไปได้ในเลขตัวนั้นก็คือ (2^(N-1))-1 และค่าน้อยสุดก็คือ -1*((2^(N-1)))

8. byte, short, int and long
ทั้งสี่ตัวนี้เป็นตัวแปรประเภทใกล้เคียงกันเพียงแต่ว่าขนาดหรือความจุต่างกัน ในตัวแปรประเภท ตัวแปรทั้ง 4 ชนิดนี้จะถูกใช้แทนจำนวนเต็มที่มีเครื่องหมาย เรามาลองดูตัวอย่างกันดีกว่าครับ

โปรแกรมที่ 1
//bytetest.java
public class bytetest {
  public static void main(String args[]) {
    byte bytevar = 0;       // byte variable, start at zero
    long counter = 0L;      // counter

    System.out.println("Start byte test");
    do {
     bytevar++;  // increment bytevar in each round
     counter++;  // increment counter in each round
     System.out.println("counter=" + counter + "  bytevar=" + bytevar);
    } while ( bytevar != 0 ); // break out of the loop if it comes back
                              // to the beginning value, zero.
  }
}

ให้ลองสังเกตผลลัพธ์ของโปรแกรมนี้ดูนะครับ คุณจะเห็นว่าหลังจากที่เราเพิ่มค่าของ bytevar ขึ้นไปทีละหนึ่งนั้น ค่าของมันเริ่มวิ่งจาก 1 (000000012) เพิ่มขึ้นจนถึง 127 (011111112) หลังจากนั้นก็กลายเป็นค่าลบ -128 (100000002) และตามด้วย -127 (100000012) และเพิ่มขึ้นไปจนถึง -1 (111111112) และกลับมาที่ 0 (000000002) ตามลำดับ

สิ่งที่คุณผู้อ่านควรจะระวังอย่างมากคือการใช้ตัวแปรแบบ byte เก็บค่าที่เป็นตัวนับ (counter) คุณผู้อ่านควรจะมั่นใจว่าการเพิ่มของตัวนับนั้นไม่เกินค่ามากที่สุดของตัวแปรแบบนั้น มิฉะนั้นมันจะกลายเป็นค่าลบและทำให้การคำนวณผิดพลาดไป คุณผู้อ่านสามารถเอาตัวอย่างข้างต้นไปลองกับตัวแปร ประเภทจำนวนเต็มชนิดอื่นๆอย่างเช่น short, int และ long โดยการเปลี่ยนตัวแปร bytevar ให้เป็นตัวแปรชนิดนั้นๆ ส่วนชนิดของตัวแปรที่ใช้เป็นตัวนับนั้นควรจะเป็นตัวแปรที่ใหญ่กว่าเนี่องจากว่าเราจะต้องครอบคลุมค่าลบทั้งหมดด้วย

9. float and double
ตัวแปรประเภท float นั้นใช้สำหรับเก็บค่าจำนวนจริง ตามหลักการแล้วค่าที่ใส่เข้าไปได้ในตัวแปรชนิดนี้นั้นควรจะใส่ค่าอะไรก็ได้ที่อยู่บนเส้นจำนวน แต่ตามความเป็นจริงแล้วไม่มีตัวแปรไม่ว่าชนิดใหนและในภาษาคอมพิวเตอร์ไดก็ตามที่สามารถบรรจุค่าทุกค่าบนเส้นจำนวนจริงได้หมด ตัวแปรแต่ละตัวมีความละเอียดต่างกัน ยกตัวอย่างเช่นตัวแปรแบบ float นั้นมีจำนวนบิตทั้งหมด 32-bit สามารถเก็บค่าที่มีความละเอียดได้ระดับหนึ่ง แต่ตัวแปรแบบ double มีขนาดเป็นสองเท่าของ float เพราะฉะนั้นคุณผู้อ่านจึงเดาได้เลยว่า double นั้นสามารถเก็บค่าตัวเลขที่มีความละเอียดได้มากกว่า float

การเก็บค่าของ float และ double นั้นไม่เหมือนกับการเก็บค่าจำนวนเต็มที่เราเคยเห็นใน byte, short, int และ long ใน 32-bit ของ float นั้นจะถูกแบ่งออกเป็นสามส่วน ส่วนแรกเรียกว่า sign bit มีขนาด 1-bit ส่วนที่สองเรียกว่า exponent ขนาด 8-bit และส่วนที่สามเรียกว่า mantissa ขนาด 23-bit ในมาตรฐานของ IEEE-754 นั้นทั้งสามส่วนจะถูกเรียงลงในเลขขนาด 32-bit ดังนี้

s eeeeeeee fffffff ffffffffffffffff

โดยที่ s แทน sign bit, e แทน exponent และ f แทน mantissa

ส่วนตัวแปรแบบ double นั้นในมาตรฐานของ IEEE-754 นั้นวางรูปแบบเหมือนกับ float แต่ต่างกันที่ exponent มี 11-bit และ mantissa มี 52-bit โดยทั่วไปแล้วค่า float และ double นั้นจะถูกคำนวณดังนี้

-1^(s)*(2^eee....e)*(1.fff....f)

โดยที่ eee....e เป็นเลขฐานสอง 2^eee....e คือ สองยกกำลัง eee....e และ 1.fff....f คือการเอาเลขหนึ่งเติมเข้าไปข้างหน้า mantissa แล้วเติมจุดทศนิยมคั่นตรงกลาง การคำนวณเลขฐานสองแบบมีจุดทศนิยมก็เหมือนกับแบบไม่มีทศนิยมเพียงแต่ว่าหลังจากจุดทศนิยมให้คูณด้วยสองยกกำลังติดลบเท่านั้นเอง ยกตัวอย่างเช่น

101.110012 = 1*2^2+0*2^1+1*2^0+1*2^-1+1*2^-2+0*2^-3+0*2^-4+1*2^-5 = 5.78125
จากการสูตรการคำนวณตัวแปรชนิด float และ double ข้างบนั้นเราจะเห็นว่ามันอยู่ในรูปของ เครื่องหมายบวกหรือลบคูณด้วยค่าหนึ่งกว่าๆและคูณด้วยสองยกกำลังบางอย่างซึ่งไม่เกิน 2^127 มาถึงจุดนี้แล้วคุณผู้อ่านควรจะลองคำนวณค่ามากสุดและค่าน้อยสุดดูว่าตรงกับในตารางหรือเปล่า

10. boolean
ตัวแปรแบบ boolean นั้นได้ถูกออกแบบมาให้ใส่ค่าได้สองอย่างคือ true หรือ false คำว่า "true" และ "false" นั้นเปรียบได้กับค่า constant สองค่าแต่ว่าฟังดูแล้วมีความหมายมากกว่า จริงๆแล้วแราสามารถเลียนแบบตัวแปรแบบนี้ด้วยตัวแปรแบบ integer แล้วตั้งกฎว่าถ้าเป็นเลขศูนย์ให้แทนค่า true ถ้าเป็นเลข 1 ให้แทนค่า false แต่ว่าการใช้ตัวแปรแบบ boolean นั้นทำให้เกิดความสับสนน้อยกว่า

โปรแกรมที่ 2
// booleantest.java
public class booleantest {
  public static void main(String args[]) {
    boolean ten;
    int a = 0;
    ten = false;
    while ( ten != true ) {
      System.out.println("a="+a);
      if ( a == 10 ) {
        ten = true;
      }
      a++;
    }
    System.out.println("true");
  }
}

11. String
ตัวแปรแบบ String จริงๆแล้วไม่ใช่ตัวแปรพื้นฐานแต่เป็นออบเจ็กที่มีอยู่ใน java library แต่ที่ผู้เขียนเอามาใส่ไว้ในบทความนี้ก็เพราะว่าตัวแปรนี้จะถูกใช้ค่อนข้างมากในตัวอย่าง เราจะมาดูกันว่าตัวแปรชนิดนี้ทำอะไรได้บ้างแต่จะไม่อธิบายในรายละเอียด คุณผู้อ่านที่สนใจควรจะอ่านเพิ่มเติมใน java documentation ที่ java.sun.com

String เป็นออบเจ็กที่ถูกออกแบบมาให้เก็บตัวอักษรหลายๆตัวเข้ามาอยู่ในตัวออบเจ็กเดียวกัน หลังจากที่เราใส่ข้อความตัวอักษรเข้าไปในตัวแปรแบบ String แล้วเราจะไม่สามารถแก้ค่านั้นได้

String stringA = "A simple test string"; // Create new String

เราสามารถทำให้สองตัวแปรแบบ String มีค่าเท่ากันได้ดังในตัวอย่าง

String stringB = stringA; // Assign one string to another

เนื่องจาก String นั้นเป็นออบเจ็ก ตัวแปร stringB นั้นจะชี้ไปหาค่าเดียวกันกับ stringA

String ที่ได้ถูก assigned ไปแล้วไม่สามารถแก้ได้แต่เราสามารถ assign ค่าอื่นให้กับ String ตัวนั้นได้ และไม่ต้องกังวลว่าจะเกิด memory leak อีกด้วย

stringA = "Another test string";

เราสามารถต่อ String สองตัวเข้าด้วยกันเป็น String ตัวที่สามได้อย่างเช่น

String stringC = stringA + stringB;

ถ้าคุณผู้อ่านอยากจะ print ค่าของตัวแปรแบบ String ก็สามารถทำได้ดังนี้

System.out.println(stringA);

หรือถ้าคุณผู้อ่านอยากจะ print สอง String ติดกันก็ให้เรียกคำสั่ง

System.out.println(stringA + stringB);

12. Literal Constant
Literal Constant หมายถึงค่าคงที่ต่าง ๆ ที่ไม่ถูกเปลี่ยนแปลงในตัวโปรแกรม ยกตัวอย่างเช่น 123, 12.86 โดยทั่วไปแล้วค่าที่เป็นตัวเลขที่ไม่มีจุดทศนิยมจะถูกแปลเป็นค่าแบบ int และตัวเลขที่มีจุดทศนิยมจะถูกแปลเป็นค่า float ยกตัวอย่างเช่น 250 นั้นจะถูกแปลเป็นค่า int แต่ 250.29 จะถูกแปลเป็นค่า float เรามีวิธีที่จะบอกคอมไพเลอร์ว่าเราอยากให้ literal constant นี้เป็นค่าแบบอะไรโดยการใส่ indicator ไว้ข้างหลังของตัวเลข

L,l -> long
F,f -> float
D,d -> double

ยกตัวอย่างเช่น

long along = 345L;
float afloat = 221f;
double adouble = 678924.250873d;

เรายังสามารถบอกคอมไพเลอร์ให้แปรค่า literal constant เป็นอย่างอื่นได้อีก ยกตัวอย่างเช่น 0X(zero and X) ใช้เป็น prefix ของค่า hexadecimal (เลขฐานสิบหก) หรือ 0(zero) เป็น prefix ของค่า  octal (เลขฐานแปด) ดังตัวอย่างข้างล่างนี้

int anint = 0X1A2F; // assign an int with a hexadecimal 1A2F
int anoct = 0762; // assign an int with an octal 762

13. Casting
Casting ก็คือการบอกคอมไพเลอร์ว่าเราต้องการให้ตัวแปรที่ต้องการกลายเป็นตัวแปรอีกแบบหนึ่งในช่วงเวลานั้น ยกตัวอย่างเช่น

float a=20.5;
int b=(int)a;
System.out.println(b);

ในบรรทัดที่สองนั้นมีความหมายว่าเอาค่า int ที่อยู่ใน a มาใส่ในตัวแปรชั่วคราวแบบ int ที่ไม่มีชื่อแล้วใส่เข้าไปในค่า b ซึ่งเป็นตัวแปรแบบ int คุณผู้อ่านจะสังเกต เห็นว่า a นั้นเป็นตัวแปรแบบ float เพราะฉะนั้นค่าหลังจากจุดทศนิยมนั้นก็จะหายไปหลังจากที่อยู่ใน b แล้ว (โปรดสังเกตว่า a นั้นก็ยังคงเป็น float อยู่เหมือนเดิม) โดยปรกติแล้วในการทำ assignment นั้นจาวาจะทำ casting ให้โดยอัตโนมัติ แล้วทำไมเราถึงต้องมี explicit casting ล่ะ ผู้เขียนจะขอยกตัวอย่างเช่นถ้าเราลองหาร ตัวเลขแบบ int สองตัวแล้วใส่เข้าไปในค่า float

int x=10, y=3;
float z = x/y;

ค่าหลังจุดทศนิยมที่ได้จากการหารนั้นจะหายไปเนื่องจากว่าทั้ง x และ y เป็น int เพราะฉะนั้นผลของการหารก็เลยกลายเป็น int ไปด้วย ถ้าเราจะให้ผลของการหาร เป็น float ล่ะก็อย่างน้อยตัวแปรตัวใดตัวหนึ่งของการหารจะต้องเป็น float เราจึงต้องทำแบบนี้

float z = (float)x/y หรือ float z = x/(float)y หรือ float z = (float)x/(float)y

14. final variable
final นั้นเหมือน กับ const ในภาษา C++ ถ้าเราบอกคอมไพเลอร์ว่าตัวแปรนี้เป็นแบบ final เราจะไม่สามารถเปลี่ยนค่าของมันอีกได้ภารในโปรแกรม การจะเปลี่ยนค่านี้ทำได้วิธีเดียวก็คือแก้ source code แล้วทำการคอมไพล์ใหม่ ยกตัวอย่างเช่น

final int a=20;
a=30; //compilation error

15. สิ่งที่คุณผู้อ่านควรจะได้รับหลังจากอ่านบทความนี้
15.1 สามารถประกาศ ตั้งค่า และตั้งค่าเริ่มต้นของตัวแปรชนิดต่าง ๆ ได้
15.2 สามารถตั้งชื่อตัวแปรได้อย่างถูกต้อง
15.3 สามารถเลือกใช้และรู้จักค่ามากสุดและน้อยสุดของตัวแปรชนิดต่าง ๆ
15.4 สามารถทำ one's และ two's complements ของเลขฐานสองได้และเข้าใจความสัมพันธ์ระหว่างค่าลบของเลขฐานสองและ complement
15.5 เข้าใจการใช้ Literal Constants ชนิดต่าง ๆ
15.6 เข้าใจถึงวัตถุประสงค์และการทำ Type Casting ของตัวแปรแต่ละชนิดได้
15.7 เข้าใจการใช้ final variable


Copyright (C) 2000 www.jarticles.com