
后端保留两位小数,前端显示却丢失了,查了下,是 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}},
array(4) { ["data"]=> array(2) { ["saled"]=> object(Illuminate\Database\Eloquent\Collection)#1235 (1) { ["items":protected]=> array(0) { } } ["money"]=> array(3) { ["maket_total"]=> float(16794.48) ["voucher_total"]=> string(6) "744.00" ["favorable_total"]=> float(509.46) } } ["status"]=> int(0) ["msg"]=> string(12) "操作成功" ["total"]=> int(0) } php的json_encode()之后: string(170) "{"data":{"saled":[],"money":{"maket_total":16794.48,"voucher_total":"744.00","favorable_total":509.46000000000004}},"status":0,"msg":"\u64cd\u4f5c\u6210\u529f","total":0}" 然后json_encode()就丢失精度了
1 TommyLemon Oct 31, 2018 也保留两位小数 |
2 TomatoYuyuko Oct 31, 2018 不了解 php 怎么做的,我这里大概思路是用 string 类型传送浮点数,然后前端再做处理。 |
3 mentalidade OP |
4 HanMeiM Oct 31, 2018 一般要么存整数,要么传 string |
5 lance7in Oct 31, 2018 string |
6 mentalidade OP |
7 micean Oct 31, 2018 钱的话谨慎用 toFixed |
8 HanMeiM Oct 31, 2018 @mentalidade 是后端啊,这里没说是钱啊。其次我们的钱单位为厘,分的更小一位 |
9 SakuraKuma Oct 31, 2018 钱的话建议传 /存储都是整数不要小数。 小数只是显示用。 这浮点数精度无解的 |
10 MrJeff Oct 31, 2018 用 string 吧 省事 |
11 westoy Oct 31, 2018 小额可以传 long, 末两位做小数, 注意控制溢出 或者传字符窜, 用 decimal 或者 gmp 既然不想在后端改, 那就无解了 浮点一时爽, 会计对账小一半订单有个几毛几分的误差就 happy 了 |
12 TomatoYuyuko Oct 31, 2018 @mentalidade 前端,一般来说前端不处理数据,只负责呈现,没有特别需求保留 2 位小数就好了。 当然数据库你肯定要存精确的,你可以直接在服务端把数字精确处理后再给前端。或者 string 之后给前端处理。 js 这类语言对浮点数处理会有误差,尽可能不要让 js 处理小数运算。 |
13 atcdef Oct 31, 2018 这个无解的,要么前端格式化一下再显示,要么后端传格式化好的字符串来。我一般都是传格式化好的字符串到前端 |
14 8e47e42 Oct 31, 2018 一般比较容易的是直接传 string,当然也可以选择成本扩大变成 bigint,当然很多库默认都不支持 bigint,然后你懂的,GG,到最后还是变成了传 string 最靠谱。 |
15 sxlzll Oct 31, 2018 如果是钱,单位可以改成分 其他的 float,确实比较稳妥的做法是两个字段,data, data_str |
16 dd112389 Nov 1, 2018 这里有个坑,前些天才遇到过. 你可以看一下 php 的 json_encode 函数的说明, 里面有写 php.ini 中的一个设置 serialize_precision 会导致 json_encode 的精度丢失问题. 将这个设置改为 16 以下应该就不会了. ini_set('serialize_precision', 15); |
17 justyue Nov 1, 2018 via iPhone 我司,钱都是转成 string 传的,安全方便 |
18 mentalidade OP @dd112389 #16 是的,我发现是 json_encode()的问题,但是上面的实际的例子,maket_total 这个值就没事,favorable_total 却发生了精度丢失,明明两个都是保留两位小数的 float ?求解 |
19 weixiangzhe Nov 1, 2018 我司都是整数 |
20 lukunlin Nov 1, 2018 .toFixed(2)一下就好了啊~ |
21 BBCCBB Nov 1, 2018 long 类型 超过 53 还是 54, js 解析也会出问题的, 还是用 string 吧. |
22 BBCCBB Nov 1, 2018 53, 54 位 |
23 promise2mm Nov 1, 2018 http://www.css88.com/archives/7340#more-7340 这里有大佬的分析,我司也遇到过 |
24 shuang Nov 1, 2018 0.495.toFixed(2) "0.49" |
  25 kran Nov 1, 2018 via iPhone 乘上 10^n 再编码成 json |
26 zjsxwc Nov 1, 2018 php7.1.x 特定小版本的问题, 加一句 ``` ini_set('serialize_precision', -1); ``` 就行 http://php-symfony.uk/json_encode-producing-unexpected-float-values-in-php-7-1/ |
27 msg7086 Nov 1, 2018 钱用浮点数这种近似表示法是作大死。只要是近似表示,就会有误差,再怎么都会有。 |
28 Jobing Nov 5, 2022 可以用这个开源库解决: https://github.com/jobinben/json-bn |