js 解析 json 精度丢失怎么处理?

2018-10-31 17:18:46 +08:00
 mentalidade

后端保留两位小数,前端显示却丢失了,查了下,是 js 解析 float 精度丢失。不想在后端改成 string,怎么让前端正确显示。

后端 php 是 float 保留两位小数,转为 json。

    ["money"]=>
    array(3) {
      ["maket_total"]=>
      float(16794.48)
      ["voucher_total"]=>
      string(6) "744.00"
      ["favorable_total"]=>
      float(509.46)
    }

前端接收却是:"money":{"maket_total":16794.48,"voucher_total":"744.00","favorable_total":509.46000000000004}},

7274 次点击
所在节点    程序员
28 条回复
TommyLemon
2018-10-31 17:28:30 +08:00
也保留两位小数
TomatoYuyuko
2018-10-31 17:30:28 +08:00
不了解 php 怎么做的,我这里大概思路是用 string 类型传送浮点数,然后前端再做处理。
mentalidade
2018-10-31 17:33:04 +08:00
@TommyLemon #1
@TomatoYuyuko #2 我用的 toFixed(2) 解决了
HanMeiM
2018-10-31 17:42:58 +08:00
一般要么存整数,要么传 string
lance7in
2018-10-31 17:51:24 +08:00
string
mentalidade
2018-10-31 17:51:51 +08:00
@HanMeiM #4
@TomatoYuyuko #2 青门你们也是后端吗?因为是钱得数值,保留两位小数的浮点数。必须要转换为 string 吗?
micean
2018-10-31 17:54:21 +08:00
钱的话谨慎用 toFixed
HanMeiM
2018-10-31 17:55:20 +08:00
@mentalidade 是后端啊,这里没说是钱啊。其次我们的钱单位为厘,分的更小一位
SakuraKuma
2018-10-31 18:00:17 +08:00
钱的话建议传 /存储都是整数不要小数。
小数只是显示用。

这浮点数精度无解的
MrJeff
2018-10-31 18:00:58 +08:00
用 string 吧 省事
westoy
2018-10-31 18:01:44 +08:00
小额可以传 long, 末两位做小数, 注意控制溢出

或者传字符窜, 用 decimal 或者 gmp

既然不想在后端改, 那就无解了

浮点一时爽, 会计对账小一半订单有个几毛几分的误差就 happy 了
TomatoYuyuko
2018-10-31 18:08:27 +08:00
@mentalidade 前端,一般来说前端不处理数据,只负责呈现,没有特别需求保留 2 位小数就好了。
当然数据库你肯定要存精确的,你可以直接在服务端把数字精确处理后再给前端。或者 string 之后给前端处理。
js 这类语言对浮点数处理会有误差,尽可能不要让 js 处理小数运算。
atcdef
2018-10-31 19:28:29 +08:00
这个无解的,要么前端格式化一下再显示,要么后端传格式化好的字符串来。我一般都是传格式化好的字符串到前端
8e47e42
2018-10-31 19:37:46 +08:00
一般比较容易的是直接传 string,当然也可以选择成本扩大变成 bigint,当然很多库默认都不支持 bigint,然后你懂的,GG,到最后还是变成了传 string 最靠谱。
sxlzll
2018-10-31 22:15:12 +08:00
如果是钱,单位可以改成分
其他的 float,确实比较稳妥的做法是两个字段,data, data_str
dd112389
2018-11-01 01:00:47 +08:00
这里有个坑,前些天才遇到过.
你可以看一下 php 的 json_encode 函数的说明, 里面有写 php.ini 中的一个设置 serialize_precision 会导致 json_encode 的精度丢失问题.
将这个设置改为 16 以下应该就不会了.
ini_set('serialize_precision', 15);
justyue
2018-11-01 08:37:13 +08:00
我司,钱都是转成 string 传的,安全方便
mentalidade
2018-11-01 09:24:47 +08:00
@dd112389 #16 是的,我发现是 json_encode()的问题,但是上面的实际的例子,maket_total 这个值就没事,favorable_total 却发生了精度丢失,明明两个都是保留两位小数的 float ?求解
weixiangzhe
2018-11-01 09:24:56 +08:00
我司都是整数
lukunlin
2018-11-01 09:51:36 +08:00
.toFixed(2)一下就好了啊~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/503097

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX