Lan Phương 9
Thành viên mới
- Tham gia
- 9/4/22
- Bài viết
- 4
- Được thích
- 0
File đính kèm
Lần chỉnh sửa cuối:
Bạn nên đổi tiêu đề thành: "Giúp lập công thức đếm số chẵn, số lẻ" cho nó gọn.
4107 923
Chào bạn,
Ô A1 có 1 chữ số lẻ và 2 chữ số chẵn, ô B1 có 1 chữ số lẻ và 3 chữ số chẵn. Ô A2 có 2 chữ số lẻ, ô B2 có 3 chữ số lẻ và 3 chữ số chẵn. Số 0 coi là chữ số chẵn. Viết công thức Có tổng cộng bao nhiêu "chữ số lẻ", bao nhiêu "chữ số chẵn" trong các ô trên ?
Code của bạn,nên thay dòng:Bạn nên đổi tiêu đề thành: "Giúp lập công thức đếm số chẵn, số lẻ" cho nó gọn.
Dạ cảm ơn anh, em thay rồi anh ạ. lúc em thấy anh hỏi kết quả trong 2 ô mong muốn là bao nhiêu thì em kiểm tra lại, thấy code cũ chưa đúng.Code của bạn,nên thay dòng:
If tam Mod 2 = so Then dem_so = dem_so + 1
bằng dòng:
If Mid(tam, i, 1) Mod 2 = so Then dem_so = dem_so + 1
Hoặc nếu có excel 365, có thể dùng công thức này để đếm số lẻ:
=SUMPRODUCT(--ISODD(MID(TEXTJOIN("",1,$A$1:$B$4),SEQUENCE(LEN(TEXTJOIN("",1,$A$1:$B$4))),1)))
Code theo kiểu của bạn là kiểu "chữ ký GPE" (*1)Dạ cảm ơn anh, em thay rồi anh ạ. lức em thấy anh hỏi kết quả trong 2 ô mong muốn là bao nhiêu thì em kiểm tra lại, thấy code cũ chưa đúng.
Vận hành của toán tử And đặc biệt và phức tạp nên ít người dùng cho "số And Số" bạn không giải thích chi tiết sợ nhiều người không hiểu và lại đi vào quên lãng như những lần trướcCode theo kiểu của bạn là kiểu "chữ ký GPE" (*1)
Code theo kiểu bình thường thì người ta code một hàm trả về cả hai số đếm. Và một hàm khác chọn số.
Viết hai hàm riêng biệt thế này được cái lợi là bạn có thể goi thẳng hàm con:
Nếu lấy hai lần riêng thì dùng hàm Index đẻ lấ phần tử thứ nhất hay thứ hai.
Nếu lấy một lần cả hai số thì chọn 2 ô và Ctrl+Shift+Enter
Function DemChanLe(ByVal so) As Variant
' ham xet so chu so chan le trong mot so
' tra ve mot array:
' voi phan tư thư nhat là so chu so le, phan tu thu hai la so chan
Dim a(1 To 2) As Long, s As String, i As Long
s = Trim(CStr(so))
For i = 1 To Len(s)
If (CInt(Mid(s, i, 1)) And 1) Then
a(1) = a(1) + 1
Else
a(2) = a(2) + 1
End If
Next i
DemChanLe = a
End Function
Function DemSoChanLe(ByVal so, Optional ByVal ChanLe=0) As Long
' ham dem so chu so chan hoac le trong mot so
' tra ve so le neu ChanLe là so le, va nguoc lai
DemSoChanLe = DemChanLe(so)(IIf(ChanLe And 1, 1, 2))
End Function
(*1) GPE's signature: trong tiếng Anh, chữ ký là ý nói cách làm đặc thù của một cá thể.
(*2) toán tử AND: tôi có nói một vài lần rồi. Khi học lập trình qua hết mức căn bản, vào mức khá rồi thì người ta phải học những mánh khoé tính toán, xem xét dữ liệu. Xét chẵn lẻ, gọt bỏ thập phân, chia 0,... là những mánh khoé cần thuộc lòng.
Trong VBA, And là toán tử bit (a And b có nghĩa là mỗi bit của a sẽ And với bit tương ứng bên b). Vì vây con toán xét chẵn lẻ của VBA rất hiệu quả khi ta chỉ cần xét bít 1.
THì giải thích:Vận hành của toán tử And đặc biệt và phức tạp nên ít người dùng cho "số And Số" bạn không giải thích chi tiết sợ nhiều người không hiểu và lại đi vào quên lãng như những lần trước
Cái này không cần bàn cãi vì nó đúng. Nhưng theo tôi vấn đề nằm ở chỗ mức độ hiệu quả hơn nhiều hay rất rất nhiều so với các phương pháp khác. Thực ra nếu ta không viết code để thực hiện 1000 lần trong 1 giây, hàng trăm lần trong 8 tiếng làm việc thì quên AND đi. Sự chênh lệch so với MOD chỉ ở mức cho các bác học đàm đạo với nhau trên bàn nhậu thôi.toán tử xét bit là một trong những toán tử tự nhiên của CPU. Vì vậy nó rất nhanh, rất ít năng lượng.
Vì vậy đem xét số chẵn lẻ bằng cách xét bit thứ nhất của nó là cách hiệu quả nhất.
Tôi không thuộc trường phái "tiết kiệm từng phần ngàn giây".Cái này không cần bàn cãi vì nó đúng. Nhưng theo tôi vấn đề nằm ở chỗ mức độ hiệu quả hơn nhiều hay rất rất nhiều so với các phương pháp khác. Thực ra nếu ta không viết code để thực hiện 1000 lần trong 1 giây, hàng trăm lần trong 8 tiếng làm việc thì quên AND đi. Sự chênh lệch so với MOD chỉ ở mức cho các bác học đàm đạo với nhau trên bàn nhậu thôi.
Trong cuộc sống, trong thực tế, đôi khi người ta lựa chọn giữa 2 phương pháp A và B không vì tiêu chí nhanh chậm khi A nhanh hơn B nhưng không đáng kể. Vd. với code để chạy thỉnh thoảng 1 lần và là code viết cho người khác, rất có thể họ có trình độ bình thường, thì nên dùng MOD. MOD theo tôi dễ hiểu với người bình thường hơn rất nhiều. Tuy nhiên nếu tôi viết code để chạy liên tục, hàng nghìn lần trong 1 giây thì tôi lại dùng AND. Trong cuộc sống sự lựa chọn tùy thuộc vào từng hoàn cảnh. Không phải lúc nào người ta cũng chọn AND thay cho MOD đâu. Cũng như viết code. Nhiều khi có thể viết code rất phức tạp và dài dòng để tốc độ chạy nhanh chóng mặt, thậm chí dùng thư viện ngoài. Nhưng nhiều khi người ta chọn code chậm hơn một chút để đánh đổi lại có code đơn giản hơn, dễ hiểu hơn, dễ bảo trì hơn. Code càng đơn giản thì cơ hội phạm lỗi càng ít.
Đây chỉ là ý kiến chủ quan thôi.
Em thì hóng món này giải sầu.tôi vẫn quan niệm toán tửu
Chính vì tôi biết có rất nhiều người như bạn nên tôi viết trong bài #11Quả thật là từ hồi biết dùng máy tính đến giờ tôi mới biết chuyện And so sánh bit như bài #10 phân tích. Thật ngạc nhiên vì với tôi, And chỉ là phép "Và" như hồi nào đến giờ của chương tập hợp và ánh xạ của môn toán đại số lớp 10, rồi được đem vào làm thành 1 toán tử của tin học.
Và (And) tôi rất tán thành những gì nêu tại bài #12. Bây chừ máy tính cá nhân đã mạnh còn hơn máy chủ những năm 90 nên có lẽ nhanh hơn tí chưa chắc đã hơn sự tiện lợi, dễ làm.
Không biết And 2 đoạn trên của tôi có kết quả là mấy không biết
MOD theo tôi dễ hiểu với người bình thường hơn rất nhiều.
1. Bạn đọc không kỹ giải thích của tôi.Quả thật là từ hồi biết dùng máy tính đến giờ tôi mới biết chuyện And so sánh bit như bài #10 phân tích. Thật ngạc nhiên vì với tôi, And chỉ là phép "Và" như hồi nào đến giờ của chương tập hợp và ánh xạ của môn toán đại số lớp 10, rồi được đem vào làm thành 1 toán tử của tin học.
Và (And) tôi rất tán thành những gì nêu tại bài #12. Bây chừ máy tính cá nhân đã mạnh còn hơn máy chủ những năm 90 nên có lẽ nhanh hơn tí chưa chắc đã hơn sự tiện lợi, dễ làm.
Không biết And 2 đoạn trên của tôi có kết quả là mấy không biết
Bài viết rất hay thiết thực và dể hiểu, nếu được bạn phát triển rộng ra thành chuyên đề về các toán tử logic để mọi người nâng cao tư duy lập trình, nhiều người tuy đọc help về các toán tử logic nhưng chưa dám dùng vì chưa hiểu tường tận, trên GPE rất hiếm sử dụng toán logicTHì giải thích:
Nên nhớ, bên trong máy thì các số được diễn đạt bằng hệ nhị phân, điển hình Integer có 16 bít, Long có 32 bít.
Khái niệm các hàng đơn vị:
- hệ thập phan có hàng đơn vị, hàng chục, hàng trăm,... Điển hình hàng chục là chữ số thứ 2 đếm từ bên phải.
Con số 123 là 1 hàng trăm, 2 hàng chục, 3 3 hàng đơn vị.
- hệ nhị phân có hàng 1, hàng 2, 4, 8, ... Điển hình hàng 4 là bit thứ 3 đếm từ nên phải.
Con số 1101 là 1 hàng 8, 1 hàng 4, 0 hàng 2 và 1 hàng 1: 8+4+0+1 = 13 (1111 là 15)
Toán từ lô-gic (AND/OR/NOT/XOR) trong VBA là toán tử tính theo bit.
NOT lật ngược tất cả các bít trong con số.
AND so sánh các bít của hai vế. Từng đơn vị (nhị phân) tương ứng nhau.
View attachment 274287
> -1 là số có tất cả các bít là 1. 0 là số có tất cả các bít là 0.
> vì vậy, khi Not lật ngược tất cả các bít thì -1 thành 0 và 0 thành -1. Lưu ý rẳng 1 lật ngược thành -2.
View attachment 274288
> 1 có bit đầu tiên (hàng 1) là 1, còn lại là 0's. 2 chỉ có bit thứ nhì là 1, còn lại là 0's. Vì vậy, khi [bit] And thì hai thằng chả khớp nhau, kết quả là 0 (tất cả các bít là 0).
> nhưng 2 (01) và 3 (11) thì cùng có bít thứ nhì là 1. Khi mang ra And thì 2 thằng chỉ khớp nhau bit thứ nhì, các bít còn lại là 0's. Kết quả là số 2.
View attachment 274289
> hình trên dễ hiểu, không cần giải thích
Trở về việc tính chẵn lẻ (chỉ tính số dương và 0). Ta biết rằng:
- trong TẤT CẢ máy tính số chẵn có bít thứ nhất là 0 và số lẻ có bit này là 1.
- toán tử xét bit là một trong những toán tử tự nhiên của CPU. Vì vậy nó rất nhanh, rất ít năng lượng.
Vì vậy đem xét số chẵn lẻ bằng cách xét bit thứ nhất của nó là cách hiệu quả nhất.
Chú thích thêm:
Trong bảng mã ASCII, A-Z chỉ khác a-z bằng bít thứ 6 (số 32). Vì vậy, ngày xưa các phép tính LCase A-Z chỉ cần +32 hay Or 32 ký tự. Ngược lại để UCase A-Z thì -32.
Tuy nhiên, qua thập niên 80's thì Mẽo chấp nhận rằng hế giới không phải chỉ mình ta, và nhìn nhận bảng mã mở rộng Unicode. Việc xét bít 32 không còn giản dị như xưa nữa.
Delphi là nền tảng lập trình hướng đối tượng....
Nhiều người cũng từng viết không chỉ 1 code trong Delphi nhưng họ không biết là trong Delphi có AND này và AND kia đâu. Vì thế mà tôi nói là MOD (operator số học) dễ hiểu hơn AND (bitwise) - thao tác trên từng bit.
...
Như trong hình khi chạy bất cứ dòng nào trong 4 dòng cuối thì đều có lỗi "Operator not applicable to this operand type"Theo như lời của bác thì tôi suy diễn (educated guess, không có nghĩa là bảo đảm 100%) Delphi rất có thể theo tinh thần này. Và đúng như bác nói, dùng nó thì phải đọc tài liệu của chính chủ xem với mỗi kiểu tham số nó sẽ làm việc thế nào, nếu hai vế khác kiểu thì kiểu nào sẽ lấn kiểu nào (bên nào bị ép kiểu). (*3)
...
(*3) Như trên, compiler rất có thể phải ép kiểu 1 vế hoặc cả hai vế để thực hiện việc dịch toán tử. (vì vậy ở tren tôi đặt tên kiểu trong dấu ngoặc, ngụ ý là sau khi ép kiểu.