Cách dễ nhất để cắt ngắn biến C++ float
có giá trị 0,6000002 thành giá trị 0,6000 và lưu trữ nó trong biến là gì?Cắt ngắn giá trị thập phân trong C++
Trả lời
Trước tiên, điều quan trọng cần biết là các số dấu phẩy động là gần đúng. Xem liên kết được cung cấp bởi @Greg Hewgill để hiểu tại sao vấn đề này không hoàn toàn có thể giải quyết được.
Nhưng dưới đây là một vài giải pháp cho vấn đề mà có lẽ sẽ đáp ứng nhu cầu của bạn:
lẽ là phương pháp tốt hơn nhưng kém hiệu quả:
char sz[64];
double lf = 0.600000002;
sprintf(sz, "%.4lf\n", lf); //sz contains 0.6000
double lf2 = atof(sz);
//lf == 0.600000002;
//lf2 == 0.6000
printf("%.4lf", lf2); //print 0.6000
Cách hiệu quả hơn, nhưng có lẽ ít chính xác:
double lf = 0.600000002;
int iSigned = lf > 0? 1: -1;
unsigned int uiTemp = (lf*pow(10, 4)) * iSigned; //Note I'm using unsigned int so that I can increase the precision of the truncate
lf = (((double)uiTemp)/pow(10,4) * iSigned);
Thực tế điều đó là không thể. Nó không phải là một giới hạn C++, mà chỉ là cách điểm trôi nổi hoạt động. Đối với nhiều giá trị không có biểu diễn chính xác, do đó bạn không thể chỉ cắt ngắn thành một số chữ số.
Bạn có thể cắt bớt khi in bằng các chuỗi định dạng printf.
Nếu bạn thực sự chỉ cần lưu trữ số lượng chữ số giới hạn, tôi khuyên bạn nên sử dụng loại dữ liệu có độ chính xác cố định thay thế.
Một tài liệu tham khảo tốt cho lý do tại sao điều này xảy ra có thể được tìm thấy trong What Every Computer Scientist Should Know About Floating Point Arithmetic bởi David Goldberg.
tôi nghĩ câu hỏi cần được hỏi ở đây là: Tại sao bạn cần cắt bớt?
Nếu nó để so sánh giữa các giá trị, có lẽ bạn nên cân nhắc sử dụng phép thử epsilon. (với một giá trị khoan dung thêm, trong trường hợp của bạn, vì nó có vẻ là lớn hơn nhiều so với epsilon được chấp nhận chung).
Nếu bạn chỉ muốn in ra dưới dạng 0,6000, hãy sử dụng các phương pháp mà người khác đã đề xuất.
roundf(myfloat * powf(10, numDigits))/powf(10, numDigits);
Ví dụ: trong trường hợp bạn cắt ngắn ba chữ số (numDigits). Bạn muốn sử dụng:
roundf(0.6000002 * 1000)/1000
// And thus:
roundf(600.0002)/1000
600/1000
0.6
(Bạn có thể muốn lưu trữ các kết quả của powf nơi nào đó, kể từ khi bạn đang sử dụng nó hai lần.)
Do cách nổi thường được lưu trữ trên máy tính, có muốn có lẽ là không chính xác. Đó là những gì bạn nhận được để sử dụng phao, mặc dù.
Sử dụng này:
floor(0.6000002*10000)/10000
Đây là một chức năng sử dụng những lời khuyên trong câu trả lời khác và một ví dụ về việc sử dụng nó:
#include <iostream>
#include <cmath>
static void Truncate(double& d, unsigned int numberOfDecimalsToKeep);
int main(int, char*[])
{
double a = 1.23456789;
unsigned int numDigits = 3;
std::cout << a << std::endl;
Truncate(a,3);
std::cout << a << std::endl;
return 0;
}
void Truncate(double& d, unsigned int numberOfDecimalsToKeep)
{
d = roundf(d * powf(10, numberOfDecimalsToKeep))/powf(10, numberOfDecimalsToKeep);
}
Tương tự như câu trả lời khác, NHƯNG bạn phải quên tròn , sàn và trunc là khác nhau theo định nghĩa.Xem định nghĩa và ví dụ đầu ra trong các cách sau:
http://www.cplusplus.com/reference/cmath/trunc/
Trong trường hợp này chúng ta cần phải trucate với một độ chính xác của 4 thập phân và thoát khỏi thập phân không đáng kể:
trunc(valueToTrunc*10000)/10000
hoặc
value = (double)((int)(valueToTrunc*10000))/(double)10000
Đối với C++ 11 bạn có thể sử dụng std::round
được xác định trong tiêu đề <cmath>
:
auto trunc_value = std::round(value_to_trunc * 10000)/10000;
- 1. Giá trị thập phân tròn trong C#
- 2. Cắt ngắn (không tròn) số thập phân trong SQL Server
- 3. So sánh hai giá trị thập lục phân trong C++
- 4. cách chuyển đổi giá trị màu RGB thành giá trị thập lục phân trong C++?
- 5. Cắt ngắn Hai chữ số thập phân mà không làm tròn
- 6. Cắt ngắn số chữ số có giá trị kép trong C#
- 7. C++ gamedev: cắt ngắn phao thành int
- 8. XML-Deserialization giá trị đôi với phân cách thập phân Đức trong C#
- 9. Truy vấn SQL để cắt ngắn thành hai dấu thập phân?
- 10. Decimal.TryParse không phân tích giá trị thập phân của tôi
- 11. Sửa lỗi trên số thập phân ngắn
- 12. Giá rack.input biến bị cắt ngắn?
- 13. Giá trị thập phân (3,2) trong MySQL luôn là 9,99
- 14. Giá trị thập phân trong SQL để chia kết quả
- 15. cắt đến 2 số thập phân
- 16. giá trị thập phân tròn tối đa là 0,01?
- 17. nhận giá trị thập phân thô từ truy vấn mysqldb
- 18. Xác thực phía máy khách MVC 3, giá trị thập phân và giá trị thập phân của mô hình (dấu tách thập phân khác nhau)
- 19. chiều rộng tính với giá trị thập phân trong Firefox, nhưng không có số thập phân trong Webkit
- 20. Chuyển đổi giá trị hex thành giá trị thập phân trong VB6
- 21. Chuyển đổi giá trị Varchar thành giá trị số nguyên/thập phân trong SQL Server
- 22. Đặt int thành giá trị âm bằng cách sử dụng chữ thập lục phân trong C#
- 23. Dấu tách thập phân C#?
- 24. XML xs: int giá trị thập lục phân
- 25. Đọc các giá trị thập lục phân bằng tiếng Anh
- 26. Số thập lục phân C#
- 27. Cắt ngắn/làm tròn toàn bộ số trong JavaScript?
- 28. Sắp xếp mảng đa chiều theo giá trị thập phân
- 29. Định dạng thập phân cho giá trị phần trăm?
- 30. Làm cách nào để cắt ngắn danh sách trong C#?
Cảm ơn bạn đã đăng liên kết Greg, tôi đã nghĩ về tài liệu chính xác đó khi tôi viết câu trả lời nhưng không thể cho cuộc sống của tôi nhớ tiêu đề. –