หน้าเว็บ

วันจันทร์ที่ 23 พฤษภาคม พ.ศ. 2554

Double.NaN == Double.Nan ได้ false !!!

วันนี้เพิ่งรู้ว่า Double.NaN == Double.Nan จะได้ค่าเป็น false เสมอ (ทดสอบในภาษา Java)

ขอสรุปวิธีแก้ปัญหาไว้ตรงนี้เผื่อคนขี้เกียจอ่านครับ
ถ่าจะทดสอบว่าค่าหนึ่งๆเป็น NaN รึเปล่าจะใช้ x == Double.NaN ไม่ได้ แต่สามารถใช้ Double.isNaN(x) ได้แทน (ภาษา Java)


ส่วนคำอธิบายขอก๊อปปี้จาก twitter ตัวเองมาแปะตามลำดับเวลาล่ะกัน (ขี้เกียจเรียบเรียงเช่นกัน :P)

- ที่ไม่เท่ากันเกิดจากคอมไพเลอร์ทำตามมาตรฐาน floating point IEEE 754 ที่บอกว่า NaN ไม่เท่ากับ NaN

- จริงๆแล้ว bit pattern ที่ represent ค่า NaN นั้นไม่ได้มีค่าเดียว แต่มีเป็น range เลย

- โดย Double.NaN จะไปเรียกเมธอด Double.longBitsToDouble(0x7ff8000000000000L) ซึ่ง 0x7ff8000000000000L เป็น bit pattern หนึ่งที่เป็นไปได้

- ซึ่งถ้าดูผิวเผินแล้วเหมือนว่า Double.NaN กับ Double.NaN ก็น่าจะได้ค่าเดียวกัน เพราะส่ง bit pattern เดียวกันเข้าไป

- (เสริม NaN มี 2 แบบถ้า bit ขึ้นต้นด้วย 0 คือ signaling NaN (sNaN)ถ้าขึ้นต้นด้วย 1 คือ quiet NaN (qNaN) ดังนั้น 0x7ff8000000000000L คือ sNaN)

- ซึ่งถ้า sNaN ถูกกระทำการทางคณิตศาสตร์แล้วค่าจะเปลี่ยนเป็น qNaN ซึ่งค่าไม่เท่าเดิม

- ในขณะที่บางโปรเซสเซอร์ เพียงแค่มีการ copy ค่า (ในระดับโปรเซสเซอร์) ก็จะทำการแปลงค่าทันที

- นอกจากแปลงประเภทแล้ว bit pattern ก็อาจเปลี่ยนไปใน range ของ NaN ที่มีอยู่

- ดังนั้นการเรียก Double.NaN หรือ Double.longBitsToDouble(0x7ff8000000000000L) ก็อาจจะได้ค่า NaN ในรูปแบบ double ที่มีbit patternไม่เหมือนเดิม

- ดังนั้นถ่าจะทดสอบว่าค่าหนึ่งๆเป็น NaN รึเปล่าจะใช้ x == Double.NaN ไม่ได้ แต่สามารถใช้ Double.isNaN(x) ได้แทน (ภาษา Java)

อ้างอิง
Javadoc
- http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Double.html#NaN
- http://download.oracle.com/javase/6/docs/api/java/lang/Double.html#longBitsToDouble(long)

IEEE 754 Standard
- http://en.wikipedia.org/wiki/IEEE_floating-point_standard
- http://en.wikipedia.org/wiki/NaN
- http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=4610935&con=yes&userType=inst

วันศุกร์ที่ 20 พฤษภาคม พ.ศ. 2554

วิธีตรวจสอบ encoding ของไฟล์บน Ubuntu

ในกรณีที่เราอยากรู้ว่าไฟล์นั้นมี encoding เป็น UTF-8, TIS-620 ฯลฯ นั้นสามารถทำได้โดยใช้คำสั่งนี้

file -bi filename

ระบบจะบอกประเภทไฟล์ และ encoding ของไฟล์มาให้ เช่น

text/x-php; charset=utf-8

หมายถึงประเภทไฟล์คือไฟล์ที่เป็นข้อความประเภท php และมี encoding เป็น utf-8 เป็นต้น


ระบบที่ทดสอบ
OS: Ubuntu 11.04

วันพฤหัสบดีที่ 5 พฤษภาคม พ.ศ. 2554

บีบไฟล์ (Compress) PDF สำหรับ Ubuntu

ถ้ามีไฟล์ PDF ซึ่งมีขนาดใหญ่มากและต้องการบีบอัดให้มีขนาดเล็กลง ขอแนะนำตัวนี้ครับ PDF Compress https://launchpad.net/compress-pdf โดยจะทำงานในรูปแบบของ Nautilus Script นั่นคือสามารถคลิกขวาที่ไฟล์แล้วสั่งงานได้เลยไม่ต้องเปิดโปรแกรมเพิ่มครับ

ที่ผมลองใช้กับไฟล์ PDF ที่มีแต่รูปขนาดใหญ่ๆรวมกัน 800MB สามารถลดลงมาได้เหลือ 700KB ครับ

วิธีการติดตั้ง
1) ดาวน์โหลดจาก https://launchpad.net/compress-pdf
2) ทำการแตก zip ไฟล์ออกมา (tar zxvf Compress-PDF-1.x.tar.gz)
3) เอาไฟล์ Compress PDF ที่แตกออกมาไปไว้ใช้ ~/.gnome2/nautilus-scripts

วิธีการใช้งาน
1) คลิกขวาไฟล์ที่ต้องการทำการบีบอัด แล้วเลือก สคริปต์ (Scripts)-> Compress PDF
2) เลือกระดับการบีบอัด (ความเล็กของไฟล์ แลกมากับ ความละเอียดของรูปหลังการบีบอัด)
3) บันทึกไฟล์ไว้ที่ที่ต้องการ

ระบบที่ทดสอบ
Compress PDF: 1.4
OS: Ubuntu 11.04 with Unity

ที่มา
https://launchpad.net/compress-pdf

ป.ล. เนื่องจากเป็น Nautilus Script ดังนั้นรองรับ GNOME แต่ไม่รู้รองรับ KDE รึเปล่า

ป.ล. 2 มีอีกเทคนิคนึงคือใช้ pdf2ps ในการแปลงไฟล์ไปเป็น .ps (postscript) ก่อนแล้วค่อยใช้ ps2pdf แปลงกลับมาเป็น pdf ก็จะมีขนาดเล็กลงมาก
ตัวอย่าง
pdf2ps original.pdf middle.ps
ps2pdf middle.ps compressed.pdf

ที่มา http://pandemoniumillusion.wordpress.com/2008/05/07/compress-a-pdf-with-pdftk/