Heim  >  Artikel  >  Backend-Entwicklung  >  涉及到金额的为什么都要保存整数?

涉及到金额的为什么都要保存整数?

WBOY
WBOYOriginal
2016-06-06 20:33:131676Durchsuche

比如金额是100.02,那么数据库中都要求存为10002

回复内容:

比如金额是100.02,那么数据库中都要求存为10002

希望对你有帮助:

  • 代码之谜(四)- 浮点数(从惊讶到思考)
  • 代码之谜(五)- 浮点数(谁偷了你的精度?)

浮点型计算不精确

为什么要用整形? 用 decimal 字段类型 不行吗? 如果涉及到计算,为了尽量保持最大的精确度,可以使用PHP 的中的 BC 数学 函数。注意,目前,浮点数在计算机中应该是无法完全精确存储的,只能最大限度。除非,你从数据库读取或从外部如GET参数获取的浮点数。

在实际的项目中,如果商品价格等 涉及到加减乘除运算时,也会按照一定约定一些规则进行取舍。 比如采用:四舍五入、向上递增、银行家舍入等等。

整数准确,速度又快。。。

浮点数不精确,计算会出现偏差

浮点数的精度:
http://php.net/manual/zh/language.types.float.php
以十进制能够精确表示的有理数如0.1或0.7,无论有多少尾数都不能被内部所使用的二进制精确表示.
因此不能在不丢失一点点精度的情况下转换为二进制的格式.
这就会造成混乱的结果,例如 floor((0.1+0.7)*10) 通常会返回 7 而不是预期中的 8.
因为该结果内部的表示其实是类似 7.9999999999999991118...
永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等.
如果确实需要更高的精度,应该使用bcmath(Binary Calculator Math)函数或者gmp(GNU Multiple Precision)函数.
http://php.net/manual/zh/ref.bc.php
http://php.net/manual/zh/ref.gmp.php

为了保险起见,我们应该使用字符串来保存大整数,并且采用比如bcmath这样的数学函数库来进行计算.
比如用PHP对账户余额进行计算时,可以使用bcmath系列任意精度数学计算函数.
加 bcadd
减 bcsub
乘 bcmul
除 bcdiv
乘方 bcpow
开平方根 bcsqrt
比较 bccomp
取模(求余数) bcmod

<code><?php var_dump((0.5+0.2+0.3)==1); // bool(true)
var_dump((0.5+0.2+0.2+0.1)==1); // bool(false)
echo bccomp('1.01', '1', 1); // 保留1位小数,此时1.01等于1.返回0,表示两个数相等.
echo bccomp('1.01', '1', 2); // 保留2位小数,此时1.01大于1.返回1,表示左边的数比右边大.
</code></code>

浮点数存在精度的问题,数据库字段采用float和double型都容易产生误差.
如果存储对精度要求比较高的数据,比如账户余额,就不能使用float型了,这时应该使用decimal型.
比如我们将MySQL数据库字段"账户余额"的数据类型定义为decimal(5,2),这样就可以存放-999.99到999.99范围内的数,并且不会出现误差.括号里左边的数表示总有效位数,右边的数表示小数位数.如果范围不够用,可以定义为decimal(10,2).

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn