![]() | 1 adzchao 2019-05-30 14:51:35 +08:00 ![]() 完全可以 看精确到多少位 后端就是这么搞的 |
![]() | 2 surfire91 2019-05-30 14:51:48 +08:00 精度够的话当然可以。 |
![]() | 3 ezksdo 2019-05-30 14:53:33 +08:00 用整数,存的时候乘 100 |
4 mawenjie 2019-05-30 15:04:49 +08:00 这不是常识吗,你敢用浮点数搞? |
![]() | 5 tabris17 2019-05-30 15:08:53 +08:00 既然有 decimal 为什么不用? |
![]() | 6 wisetc OP 各位大佬,其实我是前端,乘以 1000,然后再除以 1000,好烦哦,再前端搞来搞去太容易出错了,我就是吐个槽,看看有没有更高级的做法,比如在数据库前面加个网,好比过了就是天上一天地下一年 |
![]() | 7 neuthself 2019-05-30 15:11:38 +08:00 《高性能 MySQL 》也有讲到类似的方式,可以有但感觉没必要,直接用 decimal 吧 |
8 jifengg 2019-05-30 15:30:59 +08:00 金额,我一般都是统一单位为“分”,因为金额一般要涉及到加减的操作,用整数能保证精度。 |
![]() | 9 RubyJack 2019-05-30 15:38:24 +08:00 decimal |
![]() | 10 TheCure 2019-05-30 16:20:13 +08:00 这不是大学就学的么.. |
![]() | 11 keepeye 2019-05-30 16:23:18 +08:00 有些情况下要对金额做除法,就会出现小数了,如果不精确的话可能会导致金额出现偏差 1 分 |
![]() | 12 zgl263885 2019-05-30 16:26:12 +08:00 via iPhone 我时间戳都用的 long,前端拿到后自己再处理下。可读性和性能能好的一匹。 |
![]() | 13 wolfie 2019-05-30 16:35:28 +08:00 别像摩拜用 int 就行 |
14 txwd 2019-05-30 16:38:49 +08:00 见过用 4 位小数的,天坑 |
15 hailiang88 2019-05-30 16:39:05 +08:00 via iPhone 前端操作金额会有精度问题,需要单独处理 |
![]() | 16 nszm 2019-05-30 16:44:10 +08:00 ![]() 乘除这种给后端操作,前端这个搞不是搞事情吗 |
17 gogogogogo 2019-05-30 16:49:45 +08:00 iOS 端会有精读问题 |
![]() | 18 rockyou12 2019-05-30 16:57:32 +08:00 ![]() 后端这样存其实算是常规操作。前端好像有个 decimal.js (好像叫这个)的库可以做精确的数字运算,我觉得 lz 可能需要的是这个 |
![]() | 19 swulling 2019-05-30 16:58:00 +08:00 via iPhone 钱一定要用整数存…存成分就行了 |
20 9151 2019-05-30 17:04:09 +08:00 ![]() 楼主在搞什么山寨币? |
21 shihty5 2019-05-30 17:10:06 +08:00 ![]() BigDecimal |
![]() | 22 whypool 2019-05-30 17:12:00 +08:00 用整数,存分或者厘 |
23 aballarii 2019-05-30 17:12:10 +08:00 上面说存成分的都是没做过利率计算的吧 |
24 indingpig 2019-05-30 17:27:56 +08:00 ![]() 计算的话还是交给后台计算吧,前端计算精度有可能出问题的。比如长度超过 17 位的数,精度就开始丢失,前端最大和最小的安全整数是正负 2 的 53 次方-1 |
![]() | 25 tonghuashuai 2019-05-30 19:08:06 +08:00 Decimal |
26 julyclyde 2019-05-30 19:10:42 +08:00 ![]() 老老实实用 currency 类型,别找事 |
![]() | 27 qiyuey 2019-05-30 19:15:06 +08:00 via Android 一般是用分 |
![]() | 28 shm7 2019-05-30 19:17:22 +08:00 via iPhone 一看就不知道有个 format 叫 bank format (小数点后两位),后面的就可以拿来 tanwu 了 |
![]() | 29 SingeeKing PRO 为什么是 1000 而不是 100 …… 微信支付就是以分为单位的 |
![]() | 30 RangerWolf 2019-05-30 19:27:51 +08:00 谷歌广告的数据就是这么干的~ 你说可以么? 但是直接用 decimal 个人觉得也不错 |
![]() | 31 ETiV 2019-05-30 19:29:20 +08:00 via iPhone LZ 好厉害,我都要佩服 LZ |
![]() | 32 passerbytiny 2019-05-30 19:36:22 +08:00 ![]() @SingeeKing #27 以前虽然现金只到分,但算账的时候要算到厘。严格意义上说,微信支付是有问题的,因为现在现金是只到角的,分、厘都只能用于计算,不能用于最后的支付。 |
![]() | 33 lithiumii 2019-05-30 19:54:53 +08:00 反正我司用的 float,偶尔出现一些奇幻情况,我都惊了 |
![]() | 34 JerryCha 2019-05-30 20:48:48 +08:00 我用 String (逃 |
35 troywinter 2019-05-30 22:37:39 +08:00 #3 是正解,用整型存储最后处理时除以 100 是常识操作,不应该用其它方式,至于出错的问题 ddd 完全可以解决。 |
36 icebay 2019-05-30 22:40:20 +08:00 就用 decimal,计算用高精度函数。 |
![]() | 37 ccming 2019-05-30 22:42:40 +08:00 via iPhone @troywinter 汇率怎么处理 |
![]() | 39 limuyan44 2019-05-30 23:44:49 +08:00 via Android 真不怕无中丢钱,无中生钱? |
41 conn4575 2019-05-31 00:05:32 +08:00 via Android 说存分的肯定没真正处理过金额问题,金额不是只有加减好吗,还有除法,用整数肯定存在精度问题,老老实实用 decemal,而且最好要 12 位以上小数 |
![]() | 42 ericgui 2019-05-31 00:18:45 +08:00 应该是按照货币的最小单位 比如,美元,最小是美分,就应该乘以 100 人民币,最小是分,乘以 100 日元和韩元,似乎没有分,就是正整数,1 就是 1 元 |
43 h123123h 2019-05-31 01:03:01 +08:00 7/3 这种小数怎么办?特别是参与多次运算,精度问题误差会越来越大,看来楼上的都没做过金额处理啊 |
44 h123123h 2019-05-31 01:04:20 +08:00 老老实实用 Bigdecimal |
45 MonoLogueChi 2019-05-31 02:17:18 +08:00 via Android @keepeye 所以要多保存一位,控制除法的精确度 |
![]() | 47 ytmsdy 2019-05-31 08:06:08 +08:00 via iPhone 用 long 如果四舍五入没问题的话就用吧!要不然后期对账对死你! |
48 gavindexu 2019-05-31 08:07:05 +08:00 via iPhone 涉及除法的话, 能不能加俩字段去保留分子分母? 一定要存储结果么…… |
49 yemoluo 2019-05-31 08:49:39 +08:00 用!而且一定要要,所有计算都直接用,只有在显示用户看的时候除 100。前端也一样 |
![]() | 50 toxicant 2019-05-31 09:05:08 +08:00 via Android 金额还能让前端处理的吗... |
![]() | 51 Ciallo 2019-05-31 09:09:54 +08:00 BigDecimal 吧 |
52 22too 2019-05-31 09:10:03 +08:00 ![]() decimal 这个才是正解 1. 万一那天有个人写了一个 bug, 会不会出现金额多了 1000 倍. 无端制造风险 2. 不要理想的以为,金钱就涉及到加减法,乘除法也是经常出现的 3. 很多时候,分并不是最小单位,比如 某借呗 按照日万五收取利息, 这样会产生比分更小单位. |
![]() | 53 yidinghe 2019-05-31 09:19:31 +08:00 我们是拿分做单位。 |
![]() | 54 liuxey 2019-05-31 09:21:13 +08:00 银行一般的精度是:Decimal(18,6) -> 999999999999.999999 |
![]() | 55 AlloVince 2019-05-31 09:28:31 +08:00 既然大家说钱都是默认以元为单位,就不要做违反直觉的设计 |
56 zealinux 2019-05-31 09:31:26 +08:00 存:分子和分母 298.6734 分子:2986734 分母:10000 |
![]() | 57 chenuu 2019-05-31 09:38:36 +08:00 存货币的最小单位 |
58 justicelove 2019-05-31 09:43:43 +08:00 不单单要看存储的需要, 还要看计算的需要 |
![]() | 59 RRRoger 2019-05-31 09:46:16 +08:00 有的国家是 0.001 怎么办 我们支持多货币的 |
60 karllynn 2019-05-31 09:59:28 +08:00 用整形没有问题的,用 decimal 也可以,不过 js 的浮点数精度丢失问题好像很严重 |
62 luozic 2019-05-31 10:19:36 +08:00 小直接切了? |
![]() | 63 wisetc OP 因为有时候金额既有用户输入又有后台代入,并不十分确定金额的来向是用户输入,用户输入的情形用来显示显然不需要做放大,然后混合系统来的数据就可能会出现问题,而且金额放大 1000 倍直观上感受并不能判断是放大后的结果(例如 1000,看不出是 1 元还是 1000 元),出现不确定性。于是,前端提倡,在前端运行中的过程量都是直接的真实数据,不希望做任何的特殊处理,对请求的后台接口封装做请求参数和返回数据的处理,但是有时候涉及到遍历,和特殊处理,这又是常见的一般性问题了,金额的字段名也不固定而且有时不必需,这显然却是一种运算力的浪费。 |
![]() | 64 tailf 2019-05-31 10:23:44 +08:00 用 decimal,没有对账风险 |
![]() | 65 allanzhuo 2019-05-31 10:26:42 +08:00 我司有个十几年的所谓架构师也是这样设计的,最后他滚蛋了,哈哈哈 |
![]() | 66 wlfeng 2019-05-31 10:34:00 +08:00 和钱有关的数据老老实实用 decimal,不要搞事情,不然出问题了你哭都来不及 |
![]() | 67 wupher 2019-05-31 10:45:41 +08:00 可以 如果计算量很多很大,使用 long 会比使用 Big Decimal 效率高很多。更别提 Big Decimal 的进位策略。 但是,使用 long 也要评估是否会碰到溢出。尤其是大规模统计的情况下。 |
![]() | 68 CantSee 2019-05-31 10:56:19 +08:00 decimal 啊,这玩意跟数据库同步,多方便 |
69 jzmws 2019-05-31 11:07:14 +08:00 我第一反应为什么不用 decimal 货币型 ,最不济的用 bigint 按分来存 |
![]() | 70 SayNight 2019-05-31 11:08:26 +08:00 ![]() 如果业务场景金额只有加减,且判断以后绝对不会有复杂运算,因为是扩大倍数存储,要考虑 long 型溢出问题。 建议 BigDecimal,前面有 V 友提到银行用的是这个。曾在支付公司待过几年,每天流水十来亿,只允许使用:BigDecimal。不然很容易搞出事。 |
![]() | 71 sivacohan PRO 看你常见,如果是简单的购买行为,那你的方法是可以的。 如果是金融系统,一般做法是 Decimal 保留 4 到 6 位小数,然后定期核查,检查因为精度问题造成的损失。 最常见的常见就是 100 块钱三个人平分,最后总会有一个人多分到一分钱。 |
![]() | 73 yalin 2019-05-31 11:11:52 +08:00 听说平安一钱包大佬用这个库: https://github.com/JodaOrg/joda-money |
![]() | 74 msg7086 2019-05-31 12:00:20 +08:00 如果你是无关紧要的金融服务,比如开 VPS 收个钱什么的,那存个千分之一元也就算了。 如果是以金融为核心的服务,当然直接开大数运算咯,Decimal 或者金融专用小数格式直接用就是了。 |
![]() | 76 thet 2019-05-31 12:58:39 +08:00 via Android 我是直接用的decimal |
![]() | 77 lzj307077687 2019-05-31 13:41:20 +08:00 反正我认为我的项目 decimal 是够用的 |
![]() | 79 ZiLong 2019-05-31 14:04:57 +08:00 Bigdecimal 挺好,就是那个效率是真真的慢 |
![]() | 80 VANHOR 2019-05-31 14:07:01 +08:00 用整型,存分就可以。 |
81 shuqin2333 2019-05-31 14:17:20 +08:00 我们公司使用的 long,mysql 数据类型用的 bigint。前台存取的时候自行*/10000 |