PHP Print ค่าทศนิยมตามตำแหน่งจริงโดยไม่ต้องกำหนดค่า
วันนี้เจอปัญหาเรื่อง floating point ของ PHP เข้าไป
คือผมมีโจทย์ว่า ต้องการแสดงค่า float ที่มีทศนิยมได้หลากหลายตำแหน่ง เช่น
0.01 0.001 0.0001 0.00001 0.000001 0.0000001
คือตำแหน่งของทศนิยมมันจะหลากหลายมาก ตอนนี้ลองใช้คำสั่งปรกติได้ผลว่า
<?=myFloat?> คำสั่งแสดงผลง่ายๆ แบบนี้อ่ะนะ
จะมีปัญหาว่าถ้าทศนิยมตั้งแต่ 5 ตำแหน่งเป็นต้นไป เช่น 0.00001
จะแสดงผลเป็น 1.0E-5 ผมเลยลองเอา number_format มาครอบดู
<?=number_format(myFloat)?>ผลที่ได้จะกลายเป็น 0
ยกเว้นเราจะกำหนดตำแหน่งทศนิยมลงไปแบบนี้
<?=number_format(myFloat,5)?>ผลที่ได้จะกลายเป็น ผลที่ได้จึงจะเป็น 0.00001
ดูแล้วก็เหมือนจะได้ Solution แล้วอ่ะนะ แต่ .... ปัญหามันคือ
ถ้าทศนิยมมันไม่ใช่ 5 ตำแหน่งเสมอไปล่ะ มันอาจเป็น 4 ก็ได้ หรือ 6 ก็ได้
ด้วยคำสั่งเดียวกัน ถ้า Value มันเป็น 0.000001 ผลที่ได้จะเป็น 0.00000 ทันที
ในทางกลับกัน ถ้า Value มันเป็น 0.0001 ผลที่ได้ก็จะกลายเป็น 0.00010 เช่นกัน
ซึ่งมันก้ไม่ได้ตรงกับที่เราต้องการเลย ชิมิ
วันนี้มีวิธีแก้มาให้ตามนี้เลยครับ ใช้ rtrim เข้ามาช่วยตามตัวอย่าง
<?=rtrim(sprintf('%.8f',floatval(0.000001)),'0')?>
หลักการคือทำการแปลงค่าสูงสุด 8 ตำแหน่งไว้แล้วลบ 0 ด้านหลังออกครับ
แต่ก็จะเจอปัญหาอยู่ว่าถ้าค่าที่ใส่เข้ามีค่าตั้งแต่ 1 เป็นต้นไป
จะได้ของแถมคือมีจุดต่อท้ายครับเช่น 1. 100.
นั่นเพราะเราเอา 0 ออกแต่ไม่ได้เอา จุด ออกนั่นเอง
คือผมมีโจทย์ว่า ต้องการแสดงค่า float ที่มีทศนิยมได้หลากหลายตำแหน่ง เช่น
0.01 0.001 0.0001 0.00001 0.000001 0.0000001
คือตำแหน่งของทศนิยมมันจะหลากหลายมาก ตอนนี้ลองใช้คำสั่งปรกติได้ผลว่า
<?=myFloat?> คำสั่งแสดงผลง่ายๆ แบบนี้อ่ะนะ
จะมีปัญหาว่าถ้าทศนิยมตั้งแต่ 5 ตำแหน่งเป็นต้นไป เช่น 0.00001
จะแสดงผลเป็น 1.0E-5 ผมเลยลองเอา number_format มาครอบดู
<?=number_format(myFloat)?>ผลที่ได้จะกลายเป็น 0
ยกเว้นเราจะกำหนดตำแหน่งทศนิยมลงไปแบบนี้
<?=number_format(myFloat,5)?>ผลที่ได้จะกลายเป็น ผลที่ได้จึงจะเป็น 0.00001
ดูแล้วก็เหมือนจะได้ Solution แล้วอ่ะนะ แต่ .... ปัญหามันคือ
ถ้าทศนิยมมันไม่ใช่ 5 ตำแหน่งเสมอไปล่ะ มันอาจเป็น 4 ก็ได้ หรือ 6 ก็ได้
ด้วยคำสั่งเดียวกัน ถ้า Value มันเป็น 0.000001 ผลที่ได้จะเป็น 0.00000 ทันที
ในทางกลับกัน ถ้า Value มันเป็น 0.0001 ผลที่ได้ก็จะกลายเป็น 0.00010 เช่นกัน
ซึ่งมันก้ไม่ได้ตรงกับที่เราต้องการเลย ชิมิ
วันนี้มีวิธีแก้มาให้ตามนี้เลยครับ ใช้ rtrim เข้ามาช่วยตามตัวอย่าง
<?=rtrim(sprintf('%.8f',floatval(0.000001)),'0')?>
หลักการคือทำการแปลงค่าสูงสุด 8 ตำแหน่งไว้แล้วลบ 0 ด้านหลังออกครับ
แต่ก็จะเจอปัญหาอยู่ว่าถ้าค่าที่ใส่เข้ามีค่าตั้งแต่ 1 เป็นต้นไป
จะได้ของแถมคือมีจุดต่อท้ายครับเช่น 1. 100.
นั่นเพราะเราเอา 0 ออกแต่ไม่ได้เอา จุด ออกนั่นเอง
ความคิดเห็น
แสดงความคิดเห็น