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