Tại sao hàm INT trong VBA tính sai?

Liên hệ QC

Ếch Xanh

Thành viên tích cực
Tham gia
12/8/09
Bài viết
865
Được thích
1,572
Tôi gõ tại ô A1 là 7% (bảy phần trăm)

Tôi vào VBA và Ctrl+G để mở Immediate, tại đây tôi gõ:

?[A1]*100-Int([A1]*100)

Kết quả thu được:

8.88178419700125E-16

Lẽ ra phải bằng 0 mới đúng.

Nhưng với A1 thay bất kỳ số nào, cũng đều cho kết quả là 0 mới đau chứ!

Vấn đề lỗi này chỉ phát sinh ở 7% những số khác hình như là đúng hết!
 
Tôi gõ tại ô A1 là 7% (bảy phần trăm)

Tôi vào VBA và Ctrl+G để mở Immediate, tại đây tôi gõ:

?[A1]*100-Int([A1]*100)

Kết quả thu được:

8.88178419700125E-16

Lẽ ra phải bằng 0 mới đúng.

Nhưng với A1 thay bất kỳ số nào, cũng đều cho kết quả là 0 mới đau chứ!

Vấn đề lỗi này chỉ phát sinh ở 7% những số khác hình như là đúng hết!
Thằng INT và MOD luôn luôn tồn tại sai sót không lường trước được!
Vậy nên hãy cẩn thận. Thôi thì ROUND cho nó 1 phát đi
 
Upvote 0
Tôi gõ tại ô A1 là 7% (bảy phần trăm)

Tôi vào VBA và Ctrl+G để mở Immediate, tại đây tôi gõ:

?[A1]*100-Int([A1]*100)

Kết quả thu được:

8.88178419700125E-16

Lẽ ra phải bằng 0 mới đúng.

Nhưng với A1 thay bất kỳ số nào, cũng đều cho kết quả là 0 mới đau chứ!

Vấn đề lỗi này chỉ phát sinh ở 7% những số khác hình như là đúng hết!

không phải tại INT đâu

thử thế này sẽ biết

?7-Int([A1]*100)

?[A1]*100-7




?INT([A1]*100)-7


sẽ hiểu ngay
 
Lần chỉnh sửa cuối:
Upvote 0
PHP:
Aa=7%
?100*aa-int(100*aa)
 0

Hình như cái cửa sổ này ngó trị tại các ô khác đi vậy!
 
Upvote 0
PHP:
Aa=7%
?100*aa-int(100*aa)
 0

Hình như cái cửa sổ này ngó trị tại các ô khác đi vậy!

Ý bác Sa là khai biến rồi ráp vào à? vấn đề nằm ở chỗ tại sao nó chỉ tính sai chỉ mỗi 7% đấy chứ! Kể cả khi dùng trong mảng cũng bị dính chưởng.

Có ý định gán lên ListBox định dạng nếu Cột A (%) có số lẽ (như 5.5%, 6.3% ...) thì định dạng "0.0%" còn không có thì "0%" thế là bị lỗi này! Ẹc ... Ẹc ...
 
Lần chỉnh sửa cuối:
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
Đã nói là bạn cứ lồng hàm ROUND vào là xong, đâu cần phải tính toán chi cho phức tạp

Thầy nhìn mục đích của tên Ếch Xanh nè:

Có ý định gán lên ListBox định dạng nếu Cột A (%) có số lẽ (như 5.5%, 6.3% ...) thì định dạng "0.0%" còn không có thì "0%" thế là bị lỗi này! Ẹc ... Ẹc ...

Thế nếu tính hàm Round thì làm sao cho ra số lẽ với chẳn chứ Thầy?
 
Upvote 0
Upvote 0
ROUND đến mấy số lẻ là tùy mình. Tôi thấy đâu có vấn đề gì
Muốn chi tiết, cứ đưa file lên rồi tính tiếp

Em thử gửi bài lên, Thầy xem sẽ hiểu thôi:

Mã:
Private Sub UserForm_Initialize()
    Dim sArr As Variant, LstArr As Variant
    sArr = [PhanTram].Value
    ReDim LstArr(1 To UBound(sArr, 1), 1 To 1)
    For r = 1 To UBound(sArr, 1)
        If sArr(r, 1) * 100 - Int(sArr(r, 1) * 100) = 0 Then
        
[COLOR=#008000][B]        'Neu dat dieu kien nhu o duoi thi dung, con o tren lai sai (7%):
        'If [/B][/COLOR][COLOR=#ff0000][B]sArr(r, 1) * 1000 / 10 - Int(sArr(r, 1) * 100)[/B][/COLOR][COLOR=#008000][B] = 0 Then[/B][/COLOR]
        
           LstArr(r, 1) = Format(sArr(r, 1), "0%")
        Else
            LstArr(r, 1) = Format(sArr(r, 1), "0.0%")
        End If
    Next
    ListBox2.List = LstArr
End Sub
 

File đính kèm

  • TinhSai.xls
    24 KB · Đọc: 14
Upvote 0
Em thử gửi bài lên, Thầy xem sẽ hiểu thôi:

Mã:
Private Sub UserForm_Initialize()
    Dim sArr As Variant, LstArr As Variant
    sArr = [PhanTram].Value
    ReDim LstArr(1 To UBound(sArr, 1), 1 To 1)
    For r = 1 To UBound(sArr, 1)
        If sArr(r, 1) * 100 - Int(sArr(r, 1) * 100) = 0 Then
        
[COLOR=#008000][B]        'Neu dat dieu kien nhu o duoi thi dung, con o tren lai sai (7%):
        'If [/B][/COLOR][COLOR=#ff0000][B]sArr(r, 1) * 1000 / 10 - Int(sArr(r, 1) * 100)[/B][/COLOR][COLOR=#008000][B] = 0 Then[/B][/COLOR]
        
           LstArr(r, 1) = Format(sArr(r, 1), "0%")
        Else
            LstArr(r, 1) = Format(sArr(r, 1), "0.0%")
        End If
    Next
    ListBox2.List = LstArr
End Sub

Đưa file lên ngay từ đầu là xong chuyện rồi. Mấy trò này cần gì đến INT hay MOD chứ
PHP:
Private Sub UserForm_Initialize()
  Dim sArr As Variant, LstArr As Variant, tmp As Double, bChk As Boolean
  sArr = [PhanTram].Value
  ReDim LstArr(1 To UBound(sArr, 1), 1 To 1)
  For r = 1 To UBound(sArr, 1)
    tmp = Val(sArr(r, 1))
    bChk = CBool(InStr(Val(tmp * 100), "."))
    LstArr(r, 1) = Format(tmp, IIf(bChk, "0.", "") & "0%")
  Next
  ListBox2.List = LstArr
End Sub
 
Upvote 0
Đưa file lên ngay từ đầu là xong chuyện rồi. Mấy trò này cần gì đến INT hay MOD chứ
PHP:
Private Sub UserForm_Initialize()
  Dim sArr As Variant, LstArr As Variant, tmp As Double, bChk As Boolean
  sArr = [PhanTram].Value
  ReDim LstArr(1 To UBound(sArr, 1), 1 To 1)
  For r = 1 To UBound(sArr, 1)
    tmp = Val(sArr(r, 1))
    bChk = CBool(InStr(Val(tmp * 100), "."))
    LstArr(r, 1) = Format(tmp, IIf(bChk, "0.", "") & "0%")
  Next
  ListBox2.List = LstArr
End Sub

Đây cũng là một cách để em được học. Lúc đầu nhận định là do hàm INT tính sai số, nhưng đó từ bài của Vodoi2x mới thấy rằng toán tử bị sai. Không phải là không có cách giải quyết vấn đề, vấn đề là tính toán đơn giản vậy mà sao VBA lại sai nhỉ?
 
Upvote 0
Đây cũng là một cách để em được học. Lúc đầu nhận định là do hàm INT tính sai số, nhưng đó từ bài của Vodoi2x mới thấy rằng toán tử bị sai. Không phải là không có cách giải quyết vấn đề, vấn đề là tính toán đơn giản vậy mà sao VBA lại sai nhỉ?

Chuyện thường!
Không chỉ trong VBA mà trên bảng tính cũng thế thôi. Nói chung là mình đâu có biết bác Bill đã là gì trong trái ổi
Ẹc... Ẹc...
 
Upvote 0
Chuyện thường!
Không chỉ trong VBA mà trên bảng tính cũng thế thôi. Nói chung là mình đâu có biết bác Bill đã là gì trong trái ổi
Ẹc... Ẹc...

Cho nên bài này em đưa ra, mục đích là để cho mọi người thấy một trong những điểm lỗi của VBA mà tránh, chứ không phải cần giải pháp để khắc phục.
 
Upvote 0
Web KT
Back
Top Bottom