ทำไม int((0.15 * 10)+0.5) = 1 ???
กระทู้เก่าบอร์ด อ.Yeadram

 3,577   11
URL.หัวข้อ / URL
ทำไม int((0.15 * 10)+0.5) = 1 ???

ผมอยากรู้ว่า ทำไมถึงเป็นอย่างนี้

11 Reply in this Topic. Dispaly 1 pages and you are on page number 1

1 @R08468
ขอร่วมแสดงความคิดเห็นดังนี้ครับ
--------------------------------------

เป็นไปได้ว่าฟังก์ชั่น Int ทำกับนิพจน์ ((0.15 * 10)+0.5) ทีละส่วน
ดังนั้นจาก Int((0.15*10)+0.5) จึงเท่ากับว่า
Int(0.15*10) + Int(0.5) ซึ่งเท่ากับ 1

แต่ถ้าลองใช้โค้ดดังต่อไปนี้
Dim a as double            'ประกาศตัวแปรเป็นชนิด double เ้พื่อแสดงให้เห็นทศนิยม
a = ((0.15*10)+0.5)    'รวมค่านิพจน์เก็บไว้ในตัวแปร a
debug.print Int(a)
ผลลัพธ์ที่ได้จากการพิมพ์ค่า a คือ 2
2 @R08469
ของผมไม่เห็นเป็นนิครับ ได้ค่าออกมาเป็น 2 นะครับ
3 @R08470
สมมุติฐานแรกไม่น่าใช่ เพราะ int((0.05 * 10) + 1.5) ไม่เท่ากับ int(0.05 * 10) + Int(1.5) และคิดว่าคงไม่เป็นอย่างนั้นแน่ๆ เพราะถ้าเป็น ผู้ใช้จะไม่มีทางทราบได้อย่างแน่ชัดเลยว่า VBA จะแปลงโค้ดของเขาให้เปลี่ยนไปยังไง ทำให้การเขียนด้วยฟังก์ชั่น Int( ) ไม่สามารถเชื่อถือได้เลย

กรณีที่สองสามารถแก้ปัญหาได้ แต่ก็ไม่แน่ใจว่าจะเกิดผลกระทบยังไงบ้าง เพราะ

1) นิพจน์ (0.05 *10) นั้นได้ผลลัพธ์เป็น datatype ชนิด Double อยู่แล้ว

2) นิพจน์ ((0.05 *10) + 1.5) นั้นก็ได้ผลลัพธ์เป็น datatype ชนิด Double ด้วยเช่นกัน (เช็คได้ด้วยฟังก์ชั่น VarType(นิพนจน์) ที่คืนค่าเป็น 5 ซึ่งหมายถึง datatype เป็น Decimal)

ดังนั้น Int(นิพจน์ ที่ให้ผลเป็น Decimal) ก็น่าจะให้ผลลัพธ์ที่เหมือนกันการใส่ผลลัพธ์ของนิพจน์ลงในตัวแปร a ที่เป็น Decimal แล้วค่อยหา Int(a) อีกที

แต่กลับกลายเป็นว่า มันให้ผลไม่เหมือนกัน เมื่อผลไม่เหมือนกัน แล้วเราจะรู้ได้ยังไงว่าเมื่อไหร่เราจะต้องเขียนโปรแกรมยังไง ต้องแปลงตรงไหนบ้าง ?!?
4 @R08471
คุณ Sak ได้ 2 นี่จากที่ผมถาม หรือจากคำตอบของคุณ U&ME
5 @R08472
อ่อ โทษทีครับผมลองทำใน Query ดูไม่ได้ลองเขียนบน vba ครับ อ่านคำถามตอนแรกผมนึกว่าใช้ใน Query ครับ
6 @R08474
ปกติการเก็บค่าในคอมพิวเตอร์ มันเก็บเป็นเลขฐาน 2 (ไม่ใช่ฐาน 10)
สมมุติฐาน
อาจจะไม่ได้ค่า 2 เต็ม จะได้ 1.9999999999999999 ..
ขึ้นกับจำนวน bit

เมื่อใช้ function int จะเป็นการปัดเศษลง จึงได้ตามที่เห็น
7 @R08475
สมมุติฐานของคุณ ditasilk เหมือนที่ผมทดลองทำดูเลยครับ ว่ากำลังจะโพสตอบอยู่พอดี ฟังก์ชั่น int มันปัดเศษลงครับ จึงทำให้ได้ผลลัพธ์ดังที่เห็นครับ

============================
Sub TestInt()

x = Int((0.15 * 10) + 0.5)
y = Int(0.15 * 10) + Int(0.5)
z = Int(1.5)
zz = Int(0.5)
zzz = Int(10)
Debug.Print "x =" & x & vbCrLf & "y =" & y & vbCrLf & "z =" & z & vbCrLf & "zz =" & zz; vbCrLf & "zzz =" & zzz

End Sub
============================

x =1
y =1
z =1
zz =0
zzz =10

นี่คือค่าที่คืนมาจากฟังก์ชั่น int ครับ เวลาจะใช้อาจจะต้องระวังเรื่องการปัดเศษส่วนครับ
8 @R08476
ขอแจมด้วยคน ผมไม่ค่อยรู้เรื่องหรอกแต่ก็ชอบเจอปัญหาแนวๆนี้เหมือนกัน...
ก็เข้าใจว่า int มันปัดลง แต่ทำไมถ้าเราอ่านด้วยตามันเป็น 2 เต็มจึงปัดลงอีกหละ
ผมไปลองมาดู คิดว่าปัญหาน่าจะอยู่ที่ 0.5 ที่เขียนใน vb หรือเปล่า

ถ้าเราประกาศค่าตัวแปรแล้วกำหนดให้เท่ากับ 0.5 พอไปเข้าสูตรแล้วออกมาเป็น 2

Dim HF
HF = 0.5
Debug.Print Int((0.15 * 10) + HF) '=2
Debug.Print Int((0.15 * 10) + 0.5) '=1

ออกมาเป็น 2 ครับ
ก็เลยเข้าใจว่าน่าจะมีปัญหาที่ 0.5
แต่ก็ไม่รู้ว่ามาจากสาเหตุอะไรนะครับ
9 @R08487
ตอนนี้ค่อนข้างจะงงทีเดียว แต่ดูเหมือนว่า CDec( ) จะพอช่วยได้ ไ่ม่ว่า

Int(CDec(0.15 * 10) + 0.5)
Int((0.15 * 10) + CDec(0.5))
Int(CDec((0.15 * 10) + 0.5))

ก็จะให้ค่าเป็น 2

เหมือนจะสรุปได้ว่า ถ้ามีนิพจน์ใดถูกแปลง datatype เป็น Decimal แล้ว จะได้ผลที่ถูกต้อง แต่ก็ยังไม่รู้ว่า CDec( ) จะมีผลกระทบตรงไหนอีกหรือไม่

แต่ถ้าเปลี่ยนจาก CDec( ) ไปเป็น CDbl( ) อย่างที่คุณ U&ME บอกไว้ ผลการทำงานเป็นดังนี้

Int(CDbl(0.15 * 10) + 0.5) = 2
Int((0.15 * 10) + CDbl(0.5)) = 1 ***
Int(CDbl((0.15 * 10) + 0.5)) = 2

ซึ่งน่าจะแสดงให้เห็นว่า ปัญหานี้เกิดที่นิพจน์ (0.15 * 10)
10 @R08491
ขอตอบคุณแดน ครับ ที่บอกว่ามองด้วยตา มันจะได้ 2 ใช่ครับแต่ ฟังก์ชั่น int ปัญหาคือการปัดเศษส่วนลงครับ ดังนั้น จากโจทย์ที่ อ.สันติสุขกล่าวมานั้น หากจะแยกออกเป็น กลุ่ม คือ กลุ่ม นิพจน์ที่ (0.15*10) หากคำนวณด้วยตาเราจะได้ค่าว่า 1.5 ดังนั้นเมื่อใช้ฟังก์ชั่น int แปลงค่าที่อยู่ในนี้จะได้ int(1.5) ซึ่ง ผลลัพธ์ คือมันจะคืนค่า 1 มาให้ ครับ และ อีกนิพจน์นึง คือ ตัว 0.5 ก็เช่นเดียวกันครับ จะคืนค่าออกมาเป็น 0 ครับ ดูตัวอย่างที่ผมลองเทส ดูก็ได้ครับ ดังนั้นเมื่อ นำผลลัพธ์ทั้ง 2 ค่า มาบวกกันก็จะได้ 1+0 = 1 ครับ

============================
Sub TestInt()

x = Int((0.15 * 10) + 0.5)
y = Int(0.15 * 10) + Int(0.5)
z = Int(1.5) ===> มากจาก (0.15*10)
zz = Int(0.5)
zzz = Int(10)
Debug.Print "x =" & x & vbCrLf & "y =" & y & vbCrLf & "z =" & z & vbCrLf & "zz =" & zz; vbCrLf & "zzz =" & zzz

End Sub
============================

x =1
y =1
z =1
zz =0
zzz =10
11 @R08496
คุณ Sak ครับผมยังงงอยู่ครับ ผมรู้ว่า int มันปัดเศษลงหนะครับ แต่มันเกียวกับปัญหาข้อนี้อย่างไร ผมว่ามันไม่ได้มาแยกนิพจน์คำนวนหรอกมั๊งครับ
ผมว่าปัญหาน่าจะอยู่ที่ว่า ตัวเลขใน VB มันมีเบื้องหลังไม่เหมือนเบื้องน่า
...ตอนแรกผมเข้าใจว่าจะเป็น 0.5 เพราะลองไปกำหนค่าในตัวแปรดูแบบนี้
Dim HF
HF = 0.5
Debug.Print Int((0.15 * 10) + HF) '=2
Debug.Print Int((0.15 * 10) + 0.5) '=1
มันออกมาถูกต้อง ก็เลยยัดเยียดข้อหาให้ 0.5 เป็นแพะ

แต่ผู้ร้ายที่แท้จริงอาจเป็น (0.15*10) ตามที่คุณ สันติสุขบอกก็ได้
ลองใช้ code นี้จับผู้ร้ายดู
Debug.Print (10 * 0.15) - 1.5
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.4040s