Thư Sinh Áo Trắng
Thành viên hoạt động
- Tham gia
- 26/3/21
- Bài viết
- 160
- Được thích
- 31
Vâng bác! Vậy Log trong VBA là Logarit cơ số e luôn.Hàm Log tự nhiên trong VBA là Log(số)
Trừ phi bạn muốn làm con tính theo chuỗi khai triển Taylor. (Tính theo chuỗi Taylor cũng xứng đáng làm một bài tập viết code)Vâng bác! Vậy Log trong VBA là Logarit cơ số e luôn.
Bài 1 minh họa cho câu hỏi để các bác có để ý đến thì dễ hiểu bác ạ!Bảng tính mà còn bày đặt merge cells chỉ tổ gặp rắc rối sau này.
Bỏ merge cells đi thì mới có hứng code.
Bảng tạo Đích tạo ra là bảng có giá trị sau khi Log(x) là được ạ, không phải là tham chiếu Formula1. dùng Record Macro để chọn nguyên vùng nguồn
2. dùng Record Macro để chọn nguyên vùng đích, gõ công thức vào ô đầu và Ctrl+Enter để nó cóp công thức sang các ô còn lại.
3. chỉnh macro. Hàm Log tự nhiên trong VBA là Log(số). Hàm log theo hệ là Log(số)/Log(hệ)
Do dính dáng đến hồi quy phi tuyến nên Loga nê pe 2 vế đưa về tuyến tính.Nên Loga nê pê bảng dữ liệu đầu vào để hồi quy phi tuyến theo tuyến tính.Trừ phi bạn muốn làm con tính theo chuỗi khai triển Taylor. (Tính theo chuỗi Taylor cũng xứng đáng làm một bài tập viết code)
Cóp từ quép sai chỉ dẫn của Microsoft:
View attachment 259856
Dịch:
Hàm trả về một trị Double là Log tự nhiên của một số.
Ngữ pháp:
Log(số)
Số là tham bắt buộc, kiểu biến Double hoặc bất kỳ biểu thức số lớn hơn 0.
Chú của riêng tôi: VBA có tậ ép kiểu, chỉ cần cho nó tham là số thì nó tự đọng ép ra Double. Vả lại, Double là kiểu cao nhất của số cho nên hầu như bất cứ số nào cũng có thể ép thành Double tư. Tuy nhiên, nếu gọi hàm này với hằng thì nên thêm # sau hằng để trình dịch khỏi phải ép kiểu
Log(15#)
Chú thích:
Log tự nhiên là log với hệ e. Hằng số e có giá trị khoảng 2,718282.
Có cái nội suy đa thức sự phiền các bác không dám đưa lên.Sub t()
Const RGNGU = "c3" ' từ đây xác định vùng sử dụng của đầu vào
Const RGNGUOFFSET = 2 ' vùng sử dụng sẽ chứa 2 dòng title, dữ liệu cầnn thiết thì phải nhảy 2 dòng
Const RGDIT = "i3" ' ô bắt đầu dữ liệu cho đầu ra
Dim a As Variant, i As Long, j As Long, ia As Long, ja As Long
a = Range(RGNGU).CurrentRegion.Offset(RGNGUOFFSET, 0).Value
ia = UBound(a) - RGNGUOFFSET ' mảng dữ liệu thật ra nhỏ hơn vùng sử dụng 2 dòng
ja = UBound(a, 2)
For i = 1 To ia
For j = 1 To ja
If a(i, j) > 0 Then
a(i, j) = Log(a(i, j))
Else
a(i, j) = "#NUM!"
End If
Next j
Next i
Range(RGDIT).Resize(ia, ja).Value = a
End Sub
Có ai muốn thử viết code cho hàm Log hôn?
Mình cứ thế nghiệm giả định vào e^ làm căn cứ tìm nghiệm gần đúngTôi hỏi có ai hứng thử viết hàm triển khai Taylor của Log hay không bởi vì dạng bài này khá phổ biến với bài tập về lập trình.
Bài tập này được những người viết sách và dạy dùng để thử thách tư duy lô gic và vòng lặp của học sinh. Bình thường thì người ta dùng hàm Cosine bởi vì hàm này khá dễ khai triển. Hàm Log thử thách cao hơn một chút bởi vì nó có tới 3 dạng:
View attachment 259878
Hàm Cos chỉ có mọt dạng (vì vậy có thể dùng đệ quy thay cho vòng lặp cũng được)
View attachment 259879
(các hình trên cóp từ quép sai efunda chấm cơm)
Nó xoay thành bài toán: bạn dùng phương pháp trâu bò, đoán từ điểm thấp nhất trở đi hay dùng phép nhị phân, đoán 2 điểm?Mình cứ thế nghiệm giả định vào e^ làm căn cứ tìm nghiệm gần đúng
Bắt đầu 0 -> x ngẫu nhiên hoặc cho cố định ví dụ 10, thế vào e^ và so sánh kết quả: Nếu "gần đúng" thoát , Không bằng: Bước kế nếu lớn hơn là x/2 -> x ngược lại là x -> 2*x ...Nó xoay thành bài toán: bạn dùng phương pháp trâu bò, đoán từ điểm thấp nhất trở đi hay dùng phép nhị phân, đoán 2 điểm?
Vả lại, dùng phép tính mò như thế bạn phải đoán trước bước tăng đi của từng lượt vòng lặp.
Công thức Taylor chỉ xét lô gic, không cần phải đoán bước. Chỉ cần bạn tự đặt giới hạn "độ gần đúng"
Tôi không hiểu lắm. Bài #9 là thay vì tính log thì tính lũy thừa của e. Nếu thế thì tính luôn log thôi chứ tính lũy thừa của e thì cũng là con toán "khó như nhau". Tôi hiểu là ở đây tìm cách tính gần đúng log. Tức cách tính chỉ dùng các phép toán cộng trừ nhân chia. Phép tính lũy thừa bậc số tự nhiên có thể trình bầy bằng phép toán nhân.(*1) Cách tính nghiệm, và dùng thuật toán nhị phân như bài #9 là loại tính nằm trong bài học về thuật toán lập trình.
Function myLN(ByVal x As Double) As Double
Const saiso = 0.000000000000001
Dim k As Long, base As Double, base2 As Double, p As Double, result As Double
If x <= 0 Then Err.Raise xlErrValue
If x = 1 Then
myLN = 0
Exit Function
End If
base = (x - 1) / (x + 1)
p = 1 / base
base2 = base * base
For k = 1 To 10000 Step 2
p = p * base2
result = result + 2 * p / k
If 2 * p * base2 / (k + 2) < saiso Then Exit For
Next
myLN = result
End Function
Tôi thì thích cái Log(15#). Mong được chỉ rõ nguồn. Ngoài VBA thi cách viết đó còn dùng ở ngôn ngữ nào khác? Cảm ơnTuy nhiên, nếu gọi hàm này với hằng thì nên thêm # sau hằng để trình dịch khỏi phải ép kiểu Log(15#)
Các hàm triển khai Taylor là công thức gần đúng nên có sai số, nhiều khi khá lớn. Ví dụCode hoàn chỉnh.
Mã:Function myLN(ByVal x As Double) As Double Const saiso = 0.000000000000001 Dim k As Long, base As Double, base2 As Double, p As Double, result As Double If x <= 0 Then Err.Raise xlErrValue If x = 1 Then myLN = 0 Exit Function End If base = (x - 1) / (x + 1) p = 1 / base base2 = base * base For k = 1 To 10000 Step 2 p = p * base2 result = result + 2 * p / k If 2 * p * base2 / (k + 2) < saiso Then Exit For Next myLN = result End Function
Thực ra thì cách kinh điển của hầu hết các ngôn ngữ là gõ thêm một dấu chấm.Tôi thì thích cái Log(15#). Mong được chỉ rõ nguồn. Ngoài VBA thi cách viết đó còn dùng ở ngôn ngữ nào khác? Cảm ơn
Theo tôi, là For lặp ít quá. Tôi choCác hàm triển khai Taylor là công thức gần đúng nên có sai số, nhiều khi khá lớn. Ví dụ