如何将var x = 0.10000000000000001
四舍五入到0.10
你真的不需要。
两个值本质上是相同的值0.100000000000000005551115123126
由于浮点数精度有限。
你可以看到这里和这里的二进制表示
也许你想显示截断值-在这种情况下使用编程语言的格式化函数,如c#:
Console.WriteLine(x.ToString("0.00"));
如果要将数据输出到FileStream
,则可以使用其方法printf(string, ...)
相应地格式化数据。这种方法实际上是简单的C的知名fprintf()
。
FileStream
,您可以使用以下代码截断(技术上不等同于舍入,但非常接近)您的双精度值:
FileStream output; // the FileStream you're actually outputting to
double x = 0.1000000000001;
output.printf ("{"some_value": %.2f}", x);
// result: {"some_value": 0.10}
这将保留小数点后两位,无论其值是多少(这意味着也将输出两个零)。
如果您需要更多关于格式字符串如何工作的信息,printf()
的文档非常精确,并且包含了大量的示例。
同样,你可以看到四舍五入实际上是执行的测试从你的注释之一的例子:
// test code
double x = 2.999999999999d;
stdout.printf ("%.2f", x); // will print 3.00
上网试试!
C中的round()
函数四舍五入到整数,所以四舍五入到固定小数数的常见方法是将结果乘起来然后除以,例如round(x * 100)/100
为小数点后两位。在堆栈溢出上有一个很好的答案:我如何将浮点值限制在C小数点后的两个位置?
重要的是要理解IEEE 734浮点算术不是十进制算术。正如其他答案所述,0.1的值不能精确地表示。看看下面的例子中0.123和0.10000000000000001的四舍五入的区别。
用valac -X -lm example.vala
编译以下Vala代码,-X -lm
告诉编译器链接到C数学库:
void main () {
var x = 0.10000000000000001;
// printf style for serialization to fixed decimal places, outputs 0.10
// this is a good way to serialize to two fixed decimal places
print ("%.2fn", x);
// common way of rounding in C, outputs 0.12 in this example,
// but read example afterwards where the result is not as you expect
var y = 0.1234;
double a = Math.round(y*100)/100;
print (@"$an");
// IEEE 754 floating point arithmetic isn't decimal arithmetic,
// this outputs 0.10000000000000001, which is the same as the input
double z = Math.round(x*100)/100;
print (@"$zn");
}