2012-09-13 41 views
5

Tôi đang xây dựng một máy tính có BSP. Khi tôi thử nghiệm nó với các số khác nhau, tôi gặp phải vấn đề là các số thập phân không hiển thị chính xác.58.85 hiển thị dưới dạng 58.84999999999

Ví dụ: 58,85 -> 58,849999. Nhưng 58,84 hoặc 58,86 làm việc tốt. 58.8471 -> 54.84710000000001. Cuối cùng chữ số được gõ cuối cùng sẽ được lưu ra khỏi hư không.

Mã của tôi sau đây.

method GENERATE_NUM. 

    DATA: lv_digi type I. * number of digits after the decimal point 


    call METHOD me->get_decimal 
    RECEIVING 
     getdigits = lv_digi. 

    *if it is a natural number 
    IF lv_digi = 0. 
    IF thisnum < 0. 
     result = thisnum * 10 - newdigit. 
    ELSE. 
     result = thisnum * 10 + newdigit. 
    ENDIF. 

    *if it is a float number 
    Else. 
    IF thisnum < 0. 
     result = thisnum - (newdigit/10 ** lv_digi). 
    ELSE. 
     result = thisnum + (newdigit/10 ** lv_digi). 
    ENDIF. 

    *increase the number of decimal point by 1 
    call method me->set_decimal. 
    ENDif. 

endmethod. 

Điều tôi làm về cơ bản là mỗi khi một số được nhấp, nó gọi phương thức "generate_num". Mất THISNUM, NEWDIGIT, RESULT làm tham số.
thisnum = số hiện tại (ví dụ: 58.8)
newdigit = số nhấp chuột (ví dụ: 5)
kết quả = số được tạo (dự kiến: 58,85 nhưng trả về 58,849999).

+1

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Mysticial

+0

Sẽ hữu ích nếu bạn minh họa vị trí và cách giải quyết vấn đề này? –

+0

Đây là một trong những câu hỏi thường gặp cần giải thích rất dài. Tôi sẽ để người khác bước vào hoặc tìm một bản sao phù hợp để đóng. – Mysticial

Trả lời

7

Khi bạn muốn số thập phân có độ chính xác cố định, bạn nên sử dụng loại P (số đóng gói) thay vì phao.

Ví dụ:

DATA lv_fixed_point TYPE p LENGTH 16 DECIMALS 2. 

Điều này tạo ra một biến cố định điểm với hai chữ số sau dấu. Ý nghĩa chính xác của tham số "chiều dài" không phải là thẳng về phía trước. Từ documentation:

số Packed - loại P

Loại P dữ liệu cho phép chữ số sau dấu thập phân. Số lượng các vị trí thập phân là và được xác định trong chương trình. Giá trị phạm vi của loại dữ liệu P phụ thuộc vào kích thước của nó và số lượng các chữ số sau dấu thập phân. Kích thước hợp lệ có thể là bất kỳ giá trị nào từ 1 đến 16 byte. Hai chữ số thập phân được đóng gói thành một byte, trong khi byte cuối cùng chứa một chữ số và ký hiệu. Cho phép lên đến 14 chữ số sau dấu thập phân. Giá trị ban đầu bằng không. Khi làm việc với dữ liệu loại loại P, bạn nên đặt thuộc tính chương trình Fixed số học điểm. Nếu không, hãy nhập số P được coi là số nguyên.

Bạn có thể sử dụng dữ liệu loại P cho các giá trị như khoảng cách, trọng số, số tiền tiền, v.v.

+0

chỉ cần thay đổi loại thành p đã giải quyết được sự cố của tôi. Cảm ơn nhiều. –

0

Hoặc bạn có thể gọi CALL FUNCTION 'FLOATINGPOINT_COMPARE_ABSOLUTE' để nhân tố trong các epsilon nổi IEEE. Làm việc với điểm nổi, bạn thực sự nên tránh sử dụng so sánh trực tiếp và viết riêng của bạn với epsilons tích hợp:

IS_EQUAL 
IS_GREATER 
IS_GREATER_EQUAL 
IS_LESS 
IS_LESS_EQUAL 

là giá trị tối thiểu.

Đọc thêm about floating point here.

Tìm hiểu. Sống đi. Yêu nó.

Như một bài tập không tầm thường bạn cũng có thể đọc lên trên NaN+Inf-Inf (Cũng SNaN nếu bạn làm việc với DECFLOAT loại khác thay vì f).

+0

Nhưng đóng gói có thể là giải pháp tối ưu (nhưng không nhanh vì chúng vẫn được hiểu là CHAR-kinda) với ít nhất là về các rào cản. – Marius

Các vấn đề liên quan