Các thao tác với kiểu double trong C

lập trình


hãy giải thích nó hoạt động như thế nào? Chương trình chỉ cho tôi kết quả đúng khi tôi cộng các số nguyên, nhưng trong nhiệm vụ của mình, tôi thích sử dụng kiểu double hơn.

tùy chọn làm việc:
`

C++
for (int i = -10000; i < 10000; i++) {
    formula = s1 / (v1 + k) + s2;
    if (formula == 0) {
        break;
}
    k += 1;
}

Kết quả: 3.000000
`

nó không hoạt động chính xác:
`

C++
for (int i = -10000; i < 10000; i++) {
    formula = s1 / (v1 + k) + s2;
    if (formula == 0) {
        break;
}
    k += 0.00001;
}

Kết quả: 0,200000
`

Những gì tôi đã thử:

trong chương trình của tôi, tôi cần một kết quả chính xác hơn nên tôi không thể sử dụng kiểu int.

Giải pháp 1

Bước một là đảm bảo các biến formula, s1, s2, v1k đều thuộc loại double. Bạn thực sự không cần tất cả chúng đều tăng gấp đôi nhưng bạn muốn đảm bảo kết quả (formula) là số đôi và phép chia phải được thực hiện với đôi. Một kết quả số nguyên sẽ gần như được đảm bảo cho kết quả sai.

Bước hai là hãy cẩn thận với những so sánh bằng nhau với các giá trị kép, tức là kiểm tra xem formula là số không. Kỹ thuật thông thường cho việc này là xác định giá trị epsilon có nghĩa là “đủ gần” và so sánh với giá trị đó. Đây là một ví dụ :

C++
const double epsilon = 1.0E-9;

// do calculations here

double delta = fabs( formula );
if( delta < epsilon )
    break;

Điều này sẽ thoát ra khỏi vòng lặp for nếu formula nằm trong khoảng từ -1E-9 đến +1E-9. Bạn có thể sử dụng 1.0E-6 hoặc các giá trị khác cho epsilon miễn là nó nằm trong dung sai tính toán mong muốn của bạn.

Giải pháp 2

Có một số điều cần lưu ý ở đây. Có vẻ như chỉ có biến k được thay đổi sau mỗi vòng lặp.

C
for (int i = -10000; i < 10000; i++) {
  formula = s1 / (v1 + k) + s2;
  if (formula == 0) {
	break;
  }
  k += 0.00001;
}

Thật không may, giá trị k += 0,00001 không thể được lưu trữ chính xác dưới dạng float (hoặc double), vì vậy trình biên dịch thường sử dụng giá trị gần nhất. Nếu bây giờ bạn cộng các số kép không khớp chính xác này lại thì sai số về tổng sẽ tăng theo mỗi vòng lặp.

Hiện nay có một số cách để giải quyết vấn đề.
1. thay vì liên tục cộng lại, tốt hơn là nhân một lần với chỉ số lát cắt, điều này làm tăng độ chính xác đáng kể.
2. thay vì so sánh trực tiếp hai số float với nhau, tốt hơn nên kiểm tra sự khác biệt, theo đó sự khác biệt thường không trở thành 0 mà phải giảm xuống dưới một giá trị được chỉ định.

Sử dụng double thay vì float để có độ chính xác cao hơn sẽ chỉ giải quyết vấn đề chứ không giải quyết được.

コメント

タイトルとURLをコピーしました