前段时间看了一点python入门,写了几个运算的例子,就发现浮点数进行运算的结果并不是期望的,而是接近与期望的一个数。比如期望结果是2.4,那么实际结果可能是2.333333339,当时参考的资料上说不用在意这个,由于是入门,我也就没太在意,就当是python自己的一个问题吧。昨天在网上闲逛,又无疑碰到了这个问题,不过这个是在java下发生的。于是写了点例子,发现这个问题并非与特定语言有关,而是与计算机底层实现有关,下面就说一下这个问题。
需要注意,如果在java中使用浮点数,则默认为double。如果需要使用float,在浮点数后面加f。
public class Test {
public static void main(String[] args) {
System.out.print("直接输出2.4:");
System.out.println(2.4);
System.out.print("2.4/0.1:");
System.out.println(2.4/0.1);
System.out.print("(2.4-0.2)/0.1:");
System.out.println((2.4-0.2)/0.1);
System.out.print("直接输出2.2:");
System.out.println(2.2);
System.out.print("2.2/0.1:");
System.out.println(2.2/0.1);
System.out.print("(2.2+0.2)/0.1:");
System.out.println((2.2+0.2)/0.1);
System.out.print("2.2+0.2:");
System.out.println(2.2+0.2);
}
}
输出结果:
直接输出2.4:2.4
2.4/0.1:23.999999999999996
(2.4-0.2)/0.1:21.999999999999996
直接输出2.2:2.2
2.2/0.1:22.0
(2.2+0.2)/0.1:24.000000000000004
2.2+0.2:2.4000000000000004
我们从源代码和输出的结果进行分析。首先从结果可以知道直接输出浮点数2.2和2.4没有问题,一切正常。但是2.4/0.1我们期望应该是输出24,却输出了23.999999999999996;同样的,(2.4-0.2)/0.1期望输出是22,实际输出是21.999999999999996,(2.2+0.2)/0.1也是同样的情况。这些现象说明我们得到了非期望值,一个“错误的结果”,也就是说,在计算过程中发生了精度丢失。
前面说过,我在python中也有这样的问题,所以这种现象并不针对某种语言,而是计算机的实现造成的。众所周知,计算机只能识别二进制,所以我们的一切数据最后都转化为二进制来实现。我们发现,直接输出2.4和2.2并没有任何问题,但是一旦让其参与运算就会出错,因此精度丢失是发生在”运算“过程中的。
浮点数由两部分组成,指数和尾数。如果在转换过程中进行了运算,那么所得结果将不可知,不能保证二进制能正好准确转换为十进制。其原理参见其他参考书。
如何处理这种情况呢,可以用BigDecimal,具体使用参见JavaAPI。
分享到:
相关推荐
3. **类型转换**: 将`double`类型转换为其他数值类型,比如`int64`,如果`double`的值超出了整型的表示范围,或者小数部分被截断,都会导致精度丢失。 针对标题中提到的"将`double`类型转为`_int64`,防止精度1丢失...
虽然 `double` 提供了相对较高的精度,但在涉及精确数学运算(特别是涉及到小数值)时,由于其内部采用二进制浮点数格式存储,仍会出现精度丢失的情况。这种精度丢失的现象对于需要高精度计算的应用来说是一个常见的...
尽管`double`类型的精度较高,但在某些情况下仍然会出现精度损失的问题,尤其是在累加等连续计算操作中更为明显。 #### 二、C#中的`double`计算误差示例 ```csharp double d = 0.0; for (int i = 0; i ; i++) { d...
Java 中的双精度浮点数(double)类型在进行运算时经常出现精度丢失的问题,这是由于双精度浮点数在计算机内部的存储方式所致。双精度浮点数使用 64 位二进制数来存储小数,然而这种存储方式会导致某些小数无法精确...
解决java数值范围以及float与double精度丢失的问题 Java中的数值范围和浮点数精度问题是许多开发者经常遇到的问题。下面我们将详细探讨Java中的数值范围、float和double类型的精度问题,并且提供解决方案。 一、...
尽管`double`类型能够提供比`float`类型更高的精度,但在实际应用中,由于浮点数的二进制表示方式,有时仍然会出现精度丢失的问题。尤其在进行数学运算或比较时,这种精度问题可能会导致不准确的结果。 ### 保留两...
Java中的简单浮点数类型float和double不能够进行运算,因为大多数情况下是正常的,但是偶尔会出现如上所示的问题。这个问题其实不是JAVA的bug,因为计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制...
在这个"jisuanqi.rar_double精度"的压缩包中,我们关注的是在VC++环境下,使用double类型进行四则运算时可能出现的精度丢失问题。double类型是C++中用于表示浮点数的一种数据类型,具有较高的精度,但并非无限精确。...
这通常是由于浮点数在计算机内部以二进制表示,而某些十进制浮点数无法精确地转换为二进制,导致精度丢失。 例如,尝试执行以下代码: ```java System.out.println(19.99 + 20); System.out.println(1.0 - 0.66); ...
这种方法可以确保不会因为Double类型本身的限制而丢失精度。 - **自定义转换逻辑**:根据实际需求编写自定义的转换逻辑,例如在转换前判断BigDecimal的值是否超出了Double的表示范围,如果是,则采取其他措施如使用...
### DecimalFormat精度解决与商业运算精度问题 在进行财务计算或者商业运算时,精度问题往往成为影响最终结果准确性的关键因素之一。特别是在Java这样的语言环境中,由于其内部采用二进制浮点数表示小数的方式,这...
例如,使用`%.8lf`格式化`float`可能无法避免精度丢失,而在适当情况下,对`double`使用`%.20lf`可以保留更多位数,减少精度损失。 3. **浮点数比较**: 直接使用`==`操作符比较两个`double`类型的浮点数是否相等...
在四则运算中,数字默认被视为`Double`类型,除非明确声明为其他类型。 **2. 运算符** Kotlin提供了标准的四则运算符: - 加法:`+` - 减法:`-` - 乘法:`*` - 除法:`/` 此外,还有取余运算符(模运算):`%`,...
- float 在运算时会提升到 double 类型,即使两个 float 变量相加,也会先转换为 double 进行运算,以确保更高的精度。 2. 显式类型转换: 除了自动类型提升,程序员也可以通过显式类型转换来强制改变一个变量的...
5. **转换类型**:如果需要将`BigDecimal`转换回`double`或`float`,可以使用`doubleValue()`和`floatValue()`方法,但要注意这可能会丢失精度。 在实际开发中,`BigDecimal`的使用可以确保计算结果的准确无误,但...
然而,在处理数值计算时,通常需要将`cell`类型的数据转换为`double`类型,以便进行精确的数学运算。本文将详细讨论如何在MATLAB中进行这种类型转换,并提供相关的函数和技巧。 1. **什么是Cell类型?** `cell`是...
这主要涉及到浮点数和定点数的数据类型,以及它们在数学运算中可能出现的精度损失。本文将深入探讨这个问题,并提供解决方案。 首先,让我们理解为何会出现精度问题。在C#中,浮点数如`float`和`double`是按照IEEE ...
例如,x86架构的CPU使用双精度浮点运算单元(FPU)来处理double类型,而某些嵌入式系统可能只支持单精度浮点运算。 总结来说,C++和C语言中的精度调整是一个复杂的过程,涉及数据类型的选择、数值计算库的使用、...
然而,由于C++的特性,这些运算可能涉及到类型转换、溢出、精度丢失等问题,因此理解和掌握四则运算的调试技巧至关重要。 1. 类型转换:在C++中,不同数据类型的变量进行四则运算时,会自动进行类型提升(type ...
传统编程语言中的内置数据类型(如int、long、double等)在处理大数时存在局限性,尤其是在涉及加减乘除等基本算术操作时,容易导致溢出或精度丢失。因此,对于金融计算、密码学、大数据分析等场景,开发高精度大数...