ฉันได้ค้นหาสิ่งนี้แล้ว แต่ไม่มีใครมีตัวอย่างของเมื่อคุณจะใช้strictfp
คำหลักใน Java หรือไม่? มีใครพบการใช้งานนี้จริงหรือ
จะมีผลข้างเคียงของการใส่ลงในการดำเนินการจุดลอยตัวของฉันทั้งหมดหรือไม่
ฉันได้ค้นหาสิ่งนี้แล้ว แต่ไม่มีใครมีตัวอย่างของเมื่อคุณจะใช้strictfp
คำหลักใน Java หรือไม่? มีใครพบการใช้งานนี้จริงหรือ
จะมีผลข้างเคียงของการใส่ลงในการดำเนินการจุดลอยตัวของฉันทั้งหมดหรือไม่
คำตอบ:
Strictfp ทำให้แน่ใจว่าคุณได้รับผลลัพธ์ที่เหมือนกันแน่นอนจากการคำนวณจุดลอยตัวของคุณในทุกแพลตฟอร์ม หากคุณไม่ได้ใช้เข้มงวดffการใช้งาน JVM มีอิสระที่จะใช้ความแม่นยำเป็นพิเศษหากมี
จาก JLS :
ภายในนิพจน์ที่เข้มงวดของ FP ค่ากลางทั้งหมดจะต้องเป็นองค์ประกอบของชุดค่าลอยหรือชุดค่าคู่หมายความว่าผลลัพธ์ของนิพจน์ที่เข้มงวดของ FP ทั้งหมดจะต้องเป็นค่าที่ทำนายไว้โดยเลขคณิต IEEE 754 บนตัวถูกดำเนินการโดยใช้รูปแบบเดี่ยวและคู่ . ภายในนิพจน์ที่ไม่ใช่ FP-เข้มงวดบาง leeway จะได้รับสำหรับการใช้งานเพื่อใช้ช่วงเลขชี้กำลังขยายเพื่อแสดงผลลัพธ์กลาง; ผลกระทบสุทธิการพูดอย่างคร่าว ๆ ก็คือการคำนวณอาจทำให้เกิด "คำตอบที่ถูกต้อง" ในสถานการณ์ที่การใช้ชุดลอยพิเศษหรือชุดมูลค่าสองเท่าอาจส่งผลให้เกิดการล้นหรืออันเดอร์
ในคำอื่น ๆ มันเป็นเรื่องของการทำให้แน่ใจว่าเขียนเมื่อเรียกใช้ทุกที่จริงหมายถึงการเขียนเมื่อได้รับอย่างเท่าเทียมกัน-ผิดผลลัพธ์ทุกที่
ด้วยผลลัพธ์ที่เข้มงวดของคุณจะสามารถพกพาได้โดยที่ไม่น่าจะแม่นยำ
Wikipedia มีบทความที่ดีเกี่ยวกับหัวข้อนี้จริง ๆ แล้วที่นี่พร้อมลิงค์ไปยังข้อมูลจำเพาะ Java
การอ่านระหว่างบรรทัดความหมายก็คือถ้าคุณไม่ได้ระบุstrictfp
ดังนั้นคอมไพเลอร์ JVM และ JIT มีสิทธิ์ใช้งานเพื่อคำนวณการคำนวณทศนิยมของคุณอย่างไรก็ตามพวกเขาต้องการ เพื่อประโยชน์ของความเร็วพวกเขามักจะมอบหมายการคำนวณให้กับโปรเซสเซอร์ของคุณ ด้วยstrictfp
ในการคำนวณจะต้องเป็นไปตามมาตรฐาน IEEE 754 มาตรฐานทางคณิตศาสตร์ซึ่งในทางปฏิบัติอาจจะหมายถึงว่า JVM จะทำคำนวณ
ดังนั้นเหตุผลที่คุณต้องการใช้strictfp
? สถานการณ์หนึ่งที่ฉันเห็นคือในแอปพลิเคชันแบบกระจาย (หรือเกมแบบผู้เล่นหลายคน) ที่การคำนวณจุดลอยตัวทั้งหมดจำเป็นต้องกำหนดไว้ล่วงหน้าไม่ว่าฮาร์ดแวร์หรือซีพียูพื้นฐานจะเป็นอย่างไร การแลกเปลี่ยนคืออะไร? เวลาดำเนินการที่เป็นไปได้มากที่สุด
strictfp
การคำนวณใช้ประโยชน์จาก 8087 FPU ที่ไม่ช่วยเหลือ เป็นเพียงกรณีที่จำเป็นต้องใช้ความระมัดระวัง ดูstackoverflow.com/questions/18496560/…
strictfp
มั่นใจว่าสอดคล้องกับมาตรฐาน IEEE 754 (เพื่อให้คุณได้รับผลลัพธ์เดียวกันในทุกแพลตฟอร์ม) ข้อเสียเปรียบเพียงอย่างเดียวที่ฉันเห็นคือคุณอาจสูญเสียผลประโยชน์จากการมี FPU ที่ดีจริงๆที่มีอยู่ในฮาร์ดแวร์ของคุณ
ทุกอย่างเริ่มต้นด้วยเรื่องราว
เมื่อจาวาถูกพัฒนาโดย James Gosling เฮอร์เบิร์ตและทีมอื่น ๆ ของเขา พวกเขามีสิ่งที่บ้านี้ในใจที่เรียกว่าแพลตฟอร์มอิสระ พวกเขาต้องการทำไม้โอ๊ค (Java)ดีกว่านั้นมากจนมันจะทำงานเหมือนกันทุกเครื่องที่มีชุดคำสั่งต่างกันแม้กระทั่งใช้ระบบปฏิบัติการที่แตกต่างกัน แต่มีปัญหากับตัวเลขทศนิยมที่รู้จักกันว่าทศนิยมและสองเท่าในภาษาการเขียนโปรแกรม เครื่องจักรบางตัวสร้างประสิทธิภาพการกำหนดเป้าหมายในขณะที่ส่วนที่เหลือถูกกำหนดเป้าหมายความแม่นยำ ดังนั้นเครื่องจักรที่มีความแม่นยำมากกว่านั้นจึงมีขนาดของจุดลอยตัวเท่ากับ 80 บิตในขณะที่เครื่องจักรเดิม (มีประสิทธิภาพ / เร็วกว่า) มี 64 บิตเป็นสองเท่า แต่นี่เป็นแนวคิดหลักในการสร้างภาษาอิสระของแพลตฟอร์ม นอกจากนี้สิ่งนี้อาจนำไปสู่การสูญเสียความแม่นยำ / ข้อมูลเมื่อมีการสร้างรหัสในเครื่อง (มีขนาด 64 บิตเป็นสองเท่า) และทำงานบนเครื่องประเภทอื่น (มีขนาด 80 บิตเป็นสองเท่า)
สามารถปรับขนาดได้ แต่ไม่สามารถปรับขนาดได้ ดังนั้นพวกเขามาในแนวคิดของ strictfp เช่นจุดลอยเข้มงวด หากคุณใช้คีย์เวิร์ดนี้พร้อมคลาส / ฟังก์ชั่นดังนั้นจุดลอยตัวและดับเบิลของมันจะมีขนาดที่สอดคล้องกันกับเครื่องใด ๆ เช่น 32/64 บิตตามลำดับ
นี่คือการอ้างอิงหลายประการ:
jGuru: ตัวดัดแปลงแบบเข้มงวดคืออะไร เมื่อใดที่ฉันจะพิจารณาใช้
โดยพื้นฐานแล้วสิ่งที่ควรคำนึงถึงคือคุณสนใจหรือไม่ว่าผลลัพธ์ของนิพจน์จุดลอยตัวในโค้ดของคุณนั้นรวดเร็วหรือคาดเดาได้
strictfp
ตัวอย่างเช่นถ้าคุณต้องการคำตอบที่รหัสของคุณขึ้นมาด้วยซึ่งใช้ค่าจุดลอยตัวเพื่อให้สอดคล้องในหลายแพลตฟอร์มแล้วการใช้งาน
ฮาร์ดแวร์จุดลอยตัวคำนวณด้วยความแม่นยำมากขึ้นและมีช่วงของค่าที่มากกว่าข้อกำหนดของ Java มันจะสับสนถ้าแพลตฟอร์มบางแห่งให้ความแม่นยำมากกว่าแพลตฟอร์มอื่น ๆ เมื่อคุณใช้โมดิ
strictfp
ฟายเออร์ในเมธอดหรือคลาสคอมไพเลอร์จะสร้างโค้ดที่ยึดตามข้อกำหนด Java อย่างเคร่งครัดสำหรับผลลัพธ์ที่เหมือนกันในทุกแพลตฟอร์ม ข้างstrictfp
นอกนั้นเป็นคนขี้เกียจเล็กน้อย แต่ไม่ใช่คนขี้เกียจที่จะใช้การ์ดป้องกันใน Pentium เพื่อให้ความแม่นยำ 80 บิต
และในที่สุดก็มีข้อกำหนดภาษา Java จริง, Express15.4 การแสดงออกที่เข้มงวด FP :
ภายในนิพจน์ที่เข้มงวดของ FP ค่ากลางทั้งหมดจะต้องเป็นองค์ประกอบของชุดค่าลอยหรือชุดค่าคู่หมายความว่าผลลัพธ์ของนิพจน์ที่เข้มงวดของ FP ทั้งหมดจะต้องเป็นค่าที่ทำนายไว้โดยเลขคณิต IEEE 754 บนตัวถูกดำเนินการโดยใช้รูปแบบเดี่ยวและคู่ . ภายในนิพจน์ที่ไม่ใช่ FP-เข้มงวดบาง leeway จะได้รับสำหรับการใช้งานเพื่อใช้ช่วงเลขชี้กำลังขยายเพื่อแสดงผลลัพธ์กลาง; ผลกระทบสุทธิการพูดอย่างคร่าว ๆ ก็คือการคำนวณอาจทำให้เกิด "คำตอบที่ถูกต้อง" ในสถานการณ์ที่การใช้ชุดลอยพิเศษหรือชุดค่าสองเท่าอาจส่งผลให้เกิดการล้นหรืออันเดอร์โฟล์ว
ฉันไม่เคยใช้มันเป็นการส่วนตัว
ดังที่คำตอบอื่น ๆ ที่กล่าวถึงทำให้เกิดจุดลอยตัวกลางเพื่อให้สอดคล้องกับข้อกำหนด IEEE โดยเฉพาะโปรเซสเซอร์ x86 สามารถเก็บผลลัพธ์ระดับกลางด้วยความแม่นยำที่แตกต่างจากข้อมูลจำเพาะ IEEE สถานการณ์มีความซับซ้อนมากขึ้นเมื่อ JIT ทำการคำนวณที่เหมาะสมที่สุด คำสั่งนั้นอาจแตกต่างกันในแต่ละครั้งทำให้เกิดการปัดเศษที่แตกต่างกัน
ค่าโสหุ้ยที่เกิดขึ้นจากการเข้มงวด ff น่าจะเป็นตัวประมวลผลที่มาก บทความวิกิพีเดียในSSE2 นี้ดูเหมือนว่าจะมีข้อมูลเชิงลึกเกี่ยวกับปัญหา ดังนั้นหาก JIT สามารถสร้างคำสั่ง SSE เพื่อทำการคำนวณดูเหมือนว่าเข้มงวด fp จะไม่มีค่าใช้จ่ายใด ๆ
ในโครงการปัจจุบันของฉันมีบางสถานที่ที่ฉันใช้เข้มงวด มีจุดที่รังสีคอสมิคที่อาจเกิดขึ้นต้องถูกลบออกจากค่าพิกเซล หากนักวิจัยภายนอกบางคนมีค่าพิกเซลและรังสีคอสมิคที่อยู่ข้างหน้าพวกเขาควรจะได้รับค่าผลลัพธ์เดียวกันกับซอฟต์แวร์ของเรา
rictfp เป็นตัวดัดแปลงที่ จำกัด การคำนวณจุดลอยตัวตามมาตรฐาน IEEE 754
สิ่งนี้สามารถใช้กับคลาสทั้งหมดเช่น "publicrictfp class StrictFpModifierExample {}" หรือบนเมธอด "public void ตัวอย่างโมฆะ ()" ถ้ามันถูกใช้กับคลาสมากกว่าเมธอดทั้งหมดจะเป็นไปตาม IEEE 754 และถ้าใช้กับเมธอดนั้น ติดตาม IEEE 754
ทำไมมันถูกใช้ :: :: เนื่องจากแพลตฟอร์มที่แตกต่างกันมีฮาร์ดแวร์จุดลอยตัวที่แตกต่างกันซึ่งคำนวณด้วยความแม่นยำและช่วงของค่าที่มากกว่าข้อกำหนดจาวาที่ต้องการซึ่งอาจสร้างเอาต์พุตที่แตกต่างกันในรูปแบบที่ต่างกันดังนั้นจึงเป็นการยืนยันผลลัพธ์เดียวกัน plateforms
เข้มงวดจึงมั่นใจได้ว่าจะใช้ประโยชน์จากความเร็วและความแม่นยำของการดำเนินการจุดลอยตัวที่มีความแม่นยำสูง
ไม่มีข้อเสียกับคำสำคัญนี้ที่เราสามารถใช้เมื่อเราทำการคำนวณจุดลอยตัว
จุดสุดท้ายของฉันคือ - อะไรคือ IEEE754 ในระยะสั้น IEEE 754 กำหนดวิธีมาตรฐานสำหรับทั้งการคำนวณจุดลอยตัวและการจัดเก็บค่าจุดลอยในเดี่ยว (32- บิตใช้ใน Java ลอย) หรือสองครั้ง (64 บิตใช้ใน Java ดับเบิล) ความแม่นยำนอกจากนี้ยังกำหนดบรรทัดฐานสำหรับการคำนวณระดับกลางและสำหรับรูปแบบความแม่นยำเพิ่มเติม
strictfp
เป็นคีย์เวิร์ดและสามารถใช้เป็นโมดิฟายเออร์ที่ไม่ได้ใช้งานสำหรับคลาสหรือเมธอด (แต่ไม่มีตัวแปร) การทำเครื่องหมายคลาสว่าstrictfp
หมายความว่าโค้ดวิธีใด ๆ ในคลาสจะสอดคล้องกับกฎมาตรฐาน IEEE 754 สำหรับคะแนนลอย
หากไม่มีตัวแก้ไขนั้นจุดลอยตัวที่ใช้ในวิธีการอาจทำงานในลักษณะที่ขึ้นกับแพลตฟอร์ม ด้วยคุณสามารถคาดการณ์ว่าจุดลอยตัวของคุณจะทำงานอย่างไรโดยไม่คำนึงถึงแพลตฟอร์มพื้นฐานที่ JVM กำลังทำงานอยู่ ข้อเสียคือถ้าแพลตฟอร์มพื้นฐานรองรับความแม่นยำได้มากกว่าstrictfp
วิธีการจะไม่สามารถใช้ประโยชน์จากมันได้
หากคุณไม่ได้ประกาศคลาสในขณะที่strictfp
คุณยังสามารถรับstrictfp
พฤติกรรมตามวิธีการโดยการประกาศวิธีการเป็นstrictfp
พฤติกรรมบนพื้นฐานวิธีการโดยวิธีการด้วยการประกาศว่าเป็นวิธีการ
~ SCJP Sun®ได้รับการรับรองโปรแกรมเมอร์สำหรับ Java ™ 6 - Kathy Sierra & Bert Bates ~
ตัวอย่างด้านล่างอาจช่วยให้เข้าใจชัดเจนยิ่งขึ้น: ใน java เมื่อใดก็ตามที่เราใช้กำลังมองหาข้อมูลที่แม่นยำสำหรับการดำเนินการใด ๆ เช่นถ้าเราทำ double num1 = 10e + 102; double num2 = 8e + 10; ผลลัพธ์ = num1 + num2;
The output will be so long and not precise, becasue it is precissed by the hardware e.g JVM and JIT has the license
as long as we dont have specify it Strictfp
Marking it Strictfp will make the result Uniform on every hardware and platform, because its precised value will be same
One scenario I can see is in a distributed application (or multiplayer game) where all floating-point calculations need to
be deterministic no matter what the underlying hardware or CPU is.
คำหลัก 'เข้มงวดfp' ใช้เพื่อบังคับความแม่นยำของการคำนวณจุดลอยตัว (ลอยหรือสองเท่า) ใน Java ที่สอดคล้องกับมาตรฐาน 754 ของ IEEE อย่างชัดเจน หากคุณไม่ได้ใช้คำหลักเข้มงวด, ความแม่นยำจุดลอยตัวขึ้นอยู่กับฮาร์ดแวร์ของแพลตฟอร์มเป้าหมาย
หากมีการประกาศส่วนต่อประสานหรือคลาสที่เข้มงวดกับวิธีการทั้งหมดและประเภทที่ซ้อนกันภายในส่วนติดต่อหรือชั้นเรียนที่มีความเข้มงวดโดยนัย
ลิงค์อ้างอิง