[ว่า 'คำตอบที่ถูก' K
คัดสรรเลือก การเลือกที่K
จะเป็นแบบเฉพาะกิจเหมือนกับการเลือกVISIBLE_SHIFT
แต่การเลือกK
นั้นชัดเจนน้อยกว่าเพราะVISIBLE_SHIFT
มันไม่ได้ต่ออยู่กับคุณสมบัติการแสดงผลใด ๆ ดังนั้นรับพิษของคุณ - เลือกหรือเลือกK
VISIBLE_SHIFT
คำตอบนี้สนับสนุนการเลือกVISIBLE_SHIFT
แล้วแสดงให้เห็นถึงความยากลำบากในการเลือกK
]
แม่นยำเนื่องจากข้อผิดพลาดแบบกลมคุณไม่ควรใช้การเปรียบเทียบค่า 'แน่นอน' สำหรับการดำเนินการทางตรรกะ ในกรณีเฉพาะของคุณตำแหน่งบนจอแสดงผลภาพมันอาจไม่สำคัญว่าตำแหน่งนั้นคือ 0.0 หรือ 0.0000000003 - ความแตกต่างนั้นมองไม่เห็นด้วยตา ดังนั้นตรรกะของคุณควรเป็นดังนี้:
#define VISIBLE_SHIFT 0.0001 // for example
if (fabs(theView.frame.origin.x) < VISIBLE_SHIFT) { /* ... */ }
อย่างไรก็ตามในท้ายที่สุด 'มองไม่เห็นด้วยตา' จะขึ้นอยู่กับคุณสมบัติการแสดงผลของคุณ หากคุณสามารถผูกการแสดงผลบน (คุณควรจะสามารถ); จากนั้นเลือกVISIBLE_SHIFT
เป็นเศษส่วนของขอบเขตบนนั้น
ทีนี้คำตอบที่ถูกต้องK
จะK
มาดูกันดีกว่า 'คำตอบที่ถูกต้อง' ด้านบนพูดว่า:
K คือค่าคงที่ที่คุณเลือกเช่นนั้นข้อผิดพลาดสะสมของการคำนวณของคุณจะถูก จำกัด โดยหน่วย K ในตำแหน่งสุดท้าย (และถ้าคุณไม่แน่ใจว่าคุณได้รับข้อผิดพลาดในการคำนวณที่ถูกต้องให้ K ใหญ่กว่าสองเท่าของการคำนวณของคุณ บอกว่ามันควรจะเป็น)
K
ดังนั้นเราจึงจำเป็น หากการเดินทางK
ยากขึ้นใช้งานง่ายกว่าการเลือกฉันVISIBLE_SHIFT
คุณก็จะเป็นคนตัดสินใจว่าอะไรที่เหมาะกับคุณ เพื่อค้นหาว่าK
เรากำลังจะเขียนโปรแกรมทดสอบที่ดูK
ค่ามากมายเพื่อให้เราสามารถดูว่ามันทำงานอย่างไร ควรรู้วิธีเลือกK
อย่างไรถ้า 'คำตอบที่ถูกต้อง' สามารถใช้งานได้ ไม่มี?
เราจะใช้เป็นรายละเอียด 'คำตอบที่ถูกต้อง':
if (fabs(x-y) < K * DBL_EPSILON * fabs(x+y) || fabs(x-y) < DBL_MIN)
ลองทำตามค่าทั้งหมดของ K:
#include <math.h>
#include <float.h>
#include <stdio.h>
void main (void)
{
double x = 1e-13;
double y = 0.0;
double K = 1e22;
int i = 0;
for (; i < 32; i++, K = K/10.0)
{
printf ("K:%40.16lf -> ", K);
if (fabs(x-y) < K * DBL_EPSILON * fabs(x+y) || fabs(x-y) < DBL_MIN)
printf ("YES\n");
else
printf ("NO\n");
}
}
ebg@ebg$ gcc -o test test.c
ebg@ebg$ ./test
K:10000000000000000000000.0000000000000000 -> YES
K: 1000000000000000000000.0000000000000000 -> YES
K: 100000000000000000000.0000000000000000 -> YES
K: 10000000000000000000.0000000000000000 -> YES
K: 1000000000000000000.0000000000000000 -> YES
K: 100000000000000000.0000000000000000 -> YES
K: 10000000000000000.0000000000000000 -> YES
K: 1000000000000000.0000000000000000 -> NO
K: 100000000000000.0000000000000000 -> NO
K: 10000000000000.0000000000000000 -> NO
K: 1000000000000.0000000000000000 -> NO
K: 100000000000.0000000000000000 -> NO
K: 10000000000.0000000000000000 -> NO
K: 1000000000.0000000000000000 -> NO
K: 100000000.0000000000000000 -> NO
K: 10000000.0000000000000000 -> NO
K: 1000000.0000000000000000 -> NO
K: 100000.0000000000000000 -> NO
K: 10000.0000000000000000 -> NO
K: 1000.0000000000000000 -> NO
K: 100.0000000000000000 -> NO
K: 10.0000000000000000 -> NO
K: 1.0000000000000000 -> NO
K: 0.1000000000000000 -> NO
K: 0.0100000000000000 -> NO
K: 0.0010000000000000 -> NO
K: 0.0001000000000000 -> NO
K: 0.0000100000000000 -> NO
K: 0.0000010000000000 -> NO
K: 0.0000001000000000 -> NO
K: 0.0000000100000000 -> NO
K: 0.0000000010000000 -> NO
อาดังนั้น K ควรจะเป็น 1e16 หรือใหญ่กว่าถ้าฉันต้องการ 1e-13 ให้เป็น 'ศูนย์'
ดังนั้นฉันจะบอกว่าคุณมีสองตัวเลือก:
- ทำการคำนวณ epsilon อย่างง่าย ๆ โดยใช้วิจารณญาณทางวิศวกรรมของคุณสำหรับคุณค่าของ 'epsilon' ตามที่ฉันแนะนำ หากคุณกำลังทำกราฟิกและ 'ศูนย์' หมายถึง 'การเปลี่ยนแปลงที่มองเห็นได้' มากกว่าการตรวจสอบสินทรัพย์ภาพของคุณ (ภาพ ฯลฯ ) และตัดสินว่า epsilon สามารถเป็นอะไรได้
- อย่าพยายามคำนวณจุดใดลอยจนกว่าคุณจะได้อ่านอ้างอิงคำตอบที่ไม่ได้บรรทุกสินค้าศาสนา (และอากาศเอกของคุณในกระบวนการ)
K
และจากนั้นใช้วิจารณญาณไม่ใช่งานง่ายของคุณเพื่อเลือก
fabs(x+y)
เป็นปัญหาถ้าx
และy
(สามารถ) มีเครื่องหมายต่างกัน ยังคงเป็นคำตอบที่ดีในการเปรียบเทียบการเปรียบเทียบสินค้ากับลัทธิ