更新: 2019-09-08 javascript
c# and js 要 ceil floor 2 decimal point 都没有 build in 的 solutionhtml
好比 15.667 想 ceil to 15.67 java
作法是 Math.Ceilling(15.667 * 100) / 100 mysql
先作一个乘 100 而后除 100git
js 的用 big.jsgithub
refers : 算法
http://blog.leanote.com/post/weibo-007/mysql_float_double_decimalsql
https://frontstuff.io/how-to-handle-monetary-values-in-javascriptapp
https://www.html.cn/archives/7340
https://github.com/sarahdayan/dinero.js
https://stackoverflow.com/questions/1165761/decimal-vs-double-which-one-should-i-use-and-when
https://stackoverflow.com/questions/803225/when-should-i-use-double-instead-of-decimal
https://www.zhihu.com/question/65960911
https://exceptionnotfound.net/decimal-vs-double-and-other-tips-about-number-types-in-net/
https://stackoverflow.com/questions/149055/how-can-i-format-numbers-as-currency-string-in-javascript
https://rockyee.iteye.com/blog/891538
https://blog.csdn.net/qianlong4526888/article/details/8508012
https://www.jianshu.com/p/87627d53f77b
人作计算的时候用的是 十进制, 电脑计算和存储的时候用的是二进制
十进制转换成二进制是 ok 的, 只要没有小数点.
有小数点的时候就麻烦了, 好比
javascript 0.1 + 0.2 === 0.3 // false 结果会是 0.3xxxxxxx 后面多了不少数字
其缘由就是由于 0.1 的二进制是一个无限数字... double 用 64 位来记入数字, 确定就丢失了后面的信息...转回十进制的时候就出现了误差.
要解决这个问题,一般就是不要使用十进制小数点来运算,经过升级降级 ((0.1 x 10) + (0.2 x 10) ) / 10 就能够获得准确的数字了.
在真实的实现过程里,咱们不能直接拿 0.1 x 10, 由于这个也是一个运算,依然会错。咱们得用 string 而后本身把小数点移动去后面,而后再转换成数字
c# 的 decimal 就是替咱们干了这些事儿. 而 js 目前没有 decimal,只能靠库帮忙了.
decimal 的特色是慢, 能处理的数字小.
double 就快, 可是不精准. (这个不精准是指,当用于十进制的运算时不精准)
那么何时用 decimal or double 呢?
若是你要计算东西,而这个东西的结果是可能被"人"拿来计算的, 那么咱们就应该使用 decimal
好比:钱,积分 等等
那么 double 更多使用的场景是在游戏,图形,科学等地方。须要数字很大,运算快,可是有能够有误差的地方。
js 库
https://github.com/MikeMcl/decimal.js
或者它的姐妹 big.js 和 bignumber.js 也ok
我目前用的是 big.js 由于比较轻.
big.js 默认的 round 是四舍五入
舍入有不少种方式哦
我之前只知道 四舍五入...
Half Round Up 经典的四舍五入
Half Round Down 五舍六入
Half Round Up negetive 听过 netegive 的 round 吗? 哈哈 !
-7.5 to -7,-7.6 to -8 (这里的 up 方向是往 positive )
Hlaf Round Down negetive
-7.4 to -7,-7.5 to -8
Round Half Away From 0 (远离 0)
7.5 to 8,-7.5 to -8
Round Half Towards 0
7.5 to 7,-7.5 to -7
Round to Even
7.5 to 8(由于 8 是 even 因此四舍五入),6.5 to 6(由于 7 不是 even,因此五舍四入)
Round to Odd
7.5 to 7(由于 8 不是 odd 因此五舍四入),6.5 to 7(由于 7 是 odd,因此四舍五入)
c# 和 sql decimal 转换
c# 能够装 28 小数位置, 先后 dynamic
好比 0.123.... 小数后 28 位
或者 12.123... 小数后 27 位
它很灵活的, 反观 sql server
sql server 是 set 死的,
好比
decimal(29,28) 对应 0.123
decimal(29,27) 对应 12.123
sql server 总数能够渠道 38, 因此要尽量对上 c# 也只能是 decimal (38,28) 前面 10位,后面 28位
因此呢, 当咱们在使用 decimal 作算法是要特别敏感一些.
一种方式是定义好 decimal 的小数, 在 c# 先 round to 指定的小数后才使用. 这样 c# 和 sql 就统一了
二就是定义 38,28 等报错才处理. 毕竟10位不小. 不多遇到问题。重要是小数后好保留好,好比作除法常常就有除不完的 case
若是你 sql 保留的少于 c# 那么以后就会丢失掉那些小数了。
中小企业项目一般的作法.
首先咱们得对小数点敏感。
加减乘 int 是不会出现小数点得,除非其中一个数有小数点
除法就颇有可能会产生小数点了.
加减的状况下,小数点只会变得更少,由于进位嘛
乘法就可能会有小数点变多的状况, 好比 1.22 * 1.33, 乘法其中一个是 int 就不会变多,只会变少
加减乘是不会无穷小数点的, 即使在乘 < 0 也不会无穷
只有除会产生无穷小数点.
咱们在作计算得时候要要想清楚每一次的场景,要 round to 几位置确保人算和电脑同样。否则就会很是混乱了. 不要想说电脑能保留多少小数就保留咯...电脑是会升级的.,因此不要依赖这个,本身决定,本身 round.