Thắc mắc hàm trả về nan

Cho mình hỏi là tại sao hàm to_hop của mình lại trả về nan với mọi tham số vậy ạ.Cảm ơn mọi người.

#include <iostream>
using namespace std;
float giai_thua(float n)
{
	if (n==1) return 1;
	else return n*giai_thua(n-1);//truy hoi neu chua giam duoc xuong n=1
}
float to_hop(float k)//
{
	float tohop;
	tohop = (giai_thua(k)/(giai_thua(6)*giai_thua(k-6)));
	return tohop;
	
}
int main ()
{
	float bao,dim_mau,ti_le;
	
	cout << "Moi nhap so bao:";
	cin >> bao;
	dim_mau = to_hop(45);
	
	ti_le = (to_hop(bao)/dim_mau);
	cout <<"ti le la:" << ti_le <<endl;
	return 0;
}

Số to quá chăng hử ?

Ném thêm cái input output bạn test đây xem nào, mọi tham số là sao, chữ hay ký tự đặc biệt cũng được phải không. Nếu vậy sai là đúng rồi.

1 Like

NaN - Not a Number (Không phải một số).
Đó là khi số thực (dấu chấm động 32 - float) đã đi quá giới hạn lưu trữ của nó.

Chắc bạn cũng biết, phép tính giai thừa sẽ làm kết quả rất lớn so với số được truyền vào, thế nên bạn dùng float. Không nên dùng!. Thay vào đó bạn có thể dùng unsigned long long hoặc tương đương. Đừng nghĩ nó to (1.175494351E-38 đến 3.402823466E+38) thì nó chính xác! Nó vẫn chỉ lưu được khoảng 2^{32} = 256^4 = 4294967296 giá trị bao gồm các giá trị đặc biệt như NaN, -Infinite, +Infinite,… (tùy theo hệ thống).
Tiếp theo là phép nhân của 2 giai thừa, lớn càng lớn! Theo ưu tiên của cặp ngoặc tròn thì bạn thực hiện phép nhân rồi sau đó mới chia. Chính vì phép nhân được thực hiện trước dẫn đến NaN, mà NaN có nhân, chia, cộng và trừ với số nào đi nữa thì kết quả vẫn là NaN.
Bạn nên thực hiện phép chia trước và đừng dùng float cho phép tính chỉ thực hiện với số nguyên này.
Trong phép tính tổ hợp, bạn cũng dễ dàng nhận thấy, k!/(k-6)! cũng chính là tích của các số từ (k - 6 + 1) đến k. Tính thế này nhanh và chất lượng hơn đấy.

2 Likes

Tham khảo về min max của các kiểu dữ liệu nhé.

1 Like

À mọi input là số cụ thể là 13 đến 20.Mình cũng xửa đc rồi gán tohop về long long nó đủ bổ nhớ để lưu và hiển thị rồi nhưng mà vẫn chữa ra số đúng ^-^

45! lớn lắm.

Để tính 45 \choose 6 thì cách tính với số thực là

\frac{45}{1} \cdot \frac{44}{2} \dots \frac{40}{6}

suy từ công thức tính.

2 Likes

Mình cast tohop trong hàm to_hop về long long thì nó đủ bổ nhớ để lưu và hiển thị rồi nhưng mà vẫn chữa ra số đúng ^-^ chắc phải học nhiều hơn về mấy cái dữ liệu số lớn quá này

Vậy dùng kiểu nào mới đủ dược vậy tôi nghĩ long long là dài nhất có thể rồi

https://www.tutorialspoint.com/handling-large-numbers-in-cplusplus
Keyword: how to handle large number in c++

5 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?