对于a = 1.263839的数字,我们可以做-
float a = 1.263839
cout << fixed << setprecision(2) << a <<endl;
输出:-1.26
但是,如果我想设置数字的精度并将其存储,例如- 无需打印即可将1.263839转换为1.26。
答案 0 :(得分:5)
但是,如果我想设置数字的精度并将其存储
您可以将所需的精度存储在变量中:
int precision = 2;
随后,您可以在将浮点数转换为字符串时使用此存储的精度:
std::cout << std::setprecision(precision) << a;
我认为OP希望在不打印数字的情况下从1.263839转换为1.26。
如果 this 是您的目标,那么您首先必须意识到,最常用的浮点表示法无法表示1.26。可表示的最接近的32位二进制IEEE-754值为1.2599999904632568568359375。
因此,假设采用这种表示形式,那么您可以期望的最好值是非常接近1.26的值。在最佳情况下,我展示了该值,但由于我们需要计算值,因此请记住,除了无法精确表示值之外,还可能涉及一些微小的错误(至少在理论上;使用的示例输入没有错误)下面的算法,但应始终使用浮点数学来考虑精度损失的可能性。
计算如下:
D
std::round
到最接近的整数。D
。 P.S。有时,您可能不想四舍五入,而想精确到std::floor
或std::ceil
。这有点棘手。只是std::floor(val * D) / D
是错误的。例如,将9.70设置为两位小数,则该数字将变为9.69,这是不希望的。
在这种情况下,您可以执行以下操作:将精度乘以一个大小,四舍五入到最接近的值,然后除以多余的大小并继续:
D
* 10 std::round
到最接近的整数。std::floor
或std::ceil
D
。答案 1 :(得分:1)
您需要截断它。可能最简单的方法是将其乘以一个系数(如果是小数点后2位,则乘以100),然后将其截断或四舍五入,最后除以相同的系数。
现在,请注意,可能会出现浮点精度问题,即使经过这些操作,您的浮点数也可能不是1.26
,而是1.26000000000003
。
答案 2 :(得分:0)
如果您的目标是存储一个小数点后固定位数小的固定数字,则可以通过将其存储为带有隐式十进制乘数的整数来实现:
#include <stdio.h>
#include <math.h>
// Given a floating point value and the number of digits
// after the decimal-point that you want to preserve,
// returns an integer encoding of the value.
int ConvertFloatToFixedPrecision(float floatVal, int numDigitsAfterDecimalPoint)
{
return (int) roundf(floatVal*powf(10.0f, numDigitsAfterDecimalPoint));
}
// Given an integer encoding of your value (as returned
// by the above function), converts it back into a floating
// point value again.
float ConvertFixedPrecisionBackToFloat(int fixedPrecision, int numDigitsAfterDecimalPoint)
{
return ((float) fixedPrecision) / powf(10.0f, numDigitsAfterDecimalPoint);
}
int main(int argc, char ** arg)
{
const float val = 1.263839;
int fixedTwoDigits = ConvertFloatToFixedPrecision(val, 2);
printf("fixedTwoDigits=%i\n", fixedTwoDigits);
float backToFloat = ConvertFixedPrecisionBackToFloat(fixedTwoDigits, 2);
printf("backToFloat=%f\n", backToFloat);
return 0;
}
运行时,以上程序将显示以下输出:
fixedTwoDigits=126
backToFloat=1.260000
答案 3 :(得分:0)
如果您要谈论的是将1.26
完全存储在变量中,那么您是不可能的(完全可以1.26
起作用的机会不大,但是假设它不适合一会儿),因为浮点数不能那样工作。 There are always little inaccuracies是因为计算机处理浮点十进制数字的方式。即使您可以准确获得1.26
,也可以在尝试在计算中使用它的那一刻。
也就是说,您可以使用一些数学和截断技巧来使它们变得非常接近:
int main()
{
// our float
float a = 1.263839;
// the precision we're trying to accomplish
int precision = 100; // 3 decimal places
// because we're an int, this will keep the 126 but lose everything else
int truncated = a * precision; // multiplying by the precision ensures we keep that many digits
// convert it back to a float
// Of course, we need to ensure we're doing floating point division
float b = static_cast<float>(truncated) / precision;
cout << "a: " << a << "\n";
cout << "b: " << b << "\n";
return 0;
}
输出:
a: 1.26384
b: 1.26
请注意,此处实际上并不是1.26
。但是非常接近。
这可以通过使用setprecision()
来演示:
cout << "a: " << std:: setprecision(10) << a << "\n";
cout << "b: " << std:: setprecision(10) << b << "\n";
输出:
a: 1.263839006
b: 1.25999999
同样,它不是完全1.26
,而是非常接近,并且比以前更接近。
答案 4 :(得分:0)
使用import SwiftUI
import Combine
struct ServerMessage : Decodable {
let status, message: String
}
class HttpAuth: ObservableObject {
var didChange = PassthroughSubject<HttpAuth, Never>()
@Published var authenticated = false {
didSet{
didChange.send(self)
}
}
func checkDetails(username: String, password: String) {
guard let url = URL(string: "https://example.com") else { return }
let body: [String: String] = ["username": username, "password": password ]
let finalBody = try! JSONSerialization.data(withJSONObject: body)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = finalBody
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else { return }
let finalData = try! JSONDecoder().decode(ServerMessage.self, from: data)
print(finalData)
if finalData.status == "ok" {
DispatchQueue.global().async {
HttpAuth.authenticated = true //ERROR: Instance member 'authenticated' cannot be used on type 'HttpAuth'
print("correct credentials")
}
}
}.resume()
}
}
struct loginView: View {
@State private var username: String = ""
@State private var password: String = ""
@State var server = HttpAuth()
var body: some View {
VStack{
TextField("Username", text: $username)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(width: 200, height: nil)
.multilineTextAlignment(.center)
.disableAutocorrection(true)
.accessibility(identifier: "Username")
.autocapitalization(.none)
SecureField("Password", text: $password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(width: 200, height: nil)
.multilineTextAlignment(.center)
.disableAutocorrection(true)
.accessibility(identifier: "Password")
Button(action: {
self.server.checkDetails(username: self.username, password: self.password)
//print(self.username + ", " + self.password)
}) {
HStack{
Spacer()
Text("Login").font(.headline).foregroundColor(.white)
Spacer()
}.padding(.vertical, 10)
.background(Color.red)
.padding(.horizontal, 40)
}
if self.server.authenticated {
Text("Correct Credentials")
} //ERROR: 'String' is not convertible to 'Any'
}
}
}
struct loginView_Previews: PreviewProvider {
static var previews: some View {
loginView()
}
}
是实现这一目标的简便方法:
stringstream