大数据 爬虫Python AI Sql大数据Python

Python float 和 decimal

2019-12-17  本文已影响0人  叫我老村长

Python float 和 decimal

这里我想记录的是 Python 的 Decimal 类型和 float 的转换问题。

Python 的 Decimal 支持从 str 和 float 进行转换,比如

from decimal import Decimal

f = 3.1666666666666666
Decimal(str(f))
Decimal('3.16666666667')
Decimal(f)
Decimal('3.166666666666666518636930049979127943515777587890625')
Decimal.from_float(f)
Decimal('3.166666666666666518636930049979127943515777587890625')

比如很明显能看出一个数通过 str 或 float 直接转换都会和真正输入的不一样,这个问题是由于小数以二进制形式在计算机内表达的问题。除此之外,可以很明显看到 float 转换到 str 是经过 round 的,具体可以参考 converting-a-float-to-a-string-without-rounding-it ,最终说的都是浮点用二进制表示的问题。

所以在应对精度非常高的浮点的时候,记得一定要保留指定位的小数,尤其是在数据库设计时如果需要 Decimal 类型的,记得指定具体的精度来使数据在数据库和 Python 中都能保持一致。

MySQL设计浮点类型的字段用decimal的好处与坏处

在后端开发中,数据库MySQL我以前经常使用float和double来存储浮点型数据,但现在发现很多的精度丢失问题。

现在来看看他们的区别

decimal的格式:decimal(M,D)中D代表存储的小数位的长度,而M代表的是整数位加小数位的总长度

看看区别

建立一张表,存着三种不同的浮点型字段,各自插入相同的数据1234567.23

image

insert INTO fudianxing VALUE (1234567.23,1234567.23,1234567.23);

image

很明显float会出错,而double和decimal在这里没错误,decimal类型在更大的范围内的精度肯定会比double高。

那就来修改表结构,插入更大的值。

image

insert INTO fudianxing VALUE (1234567.23,12345671111111111111111.23,12345671111111111111111.23);

image

这里看出decimal类型更加的好用了吧,所以大家搞起来。

先总结几个好处和缺点

float和double都是采用二进制的格式存储的,decimal在存储时采用字符串存储,能够很好地保留小数地精度。

但缺点是向decimal类型字段插入超过定义的数字会省略后几位的数字,并输出警告:(数据库版本为10.1.37-MariaDB)

比如decimal(5,2),插入222.22时是正常的;插入222.222时则省略最后一位,插入222.22;插入222.225时,就会四舍五入插入222.23;

如上定义,当插入一个四位数4396的数字时就会插入一个最大值999.99,并输出警告,不会报错;

当插入整数888时就会显示888,并不会显示888.00,这就比其他两个浮点型好。

如上是decimal的定义,我觉得是一个缺点吧,因为他们居然都插入成功了,并且以边界值来处理,但严格意义上来说并不算缺点,算是一个对错误的兼容。

现在就来说优点:

  1. 数值以字符串的形式保存,存储了一个准确(精确)的数字表达法,不存储值的近似值。
    这种方法很好地处理float和double类型都会发生的错误,因为他们都是以二进制存储的,所以有一定的误差。一个字符用于值的每一位、小数点

  2. decimal有更多的位数保存数值

    float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位)

    double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E308(15个有效位)

    decimal:数字型,128bit,不存在精度损失,常用于银行帐目计算。(28个有效位)
    decimal(a,b)

    参数说明

    a指定指定小数点左边和右边可以存储的十进制数字的最大个数,最大精度38。
    b指定小数点右边可以存储的十进制数字的最大个数。小数位数必须是从 0 到 a之间的值。默认小数位数是 0。

  3. decimal 数据类型最多可存储 38 个数字,所有数字都能够放到小数点的右边。

总结:数值用decimal就对了,因为数字迟早会变大的。

上一篇下一篇

猜你喜欢

热点阅读