fix: preserve canonical floating-point BigDecimal conversion - #7819
Open
DarrenChangJR wants to merge 1 commit into
Open
fix: preserve canonical floating-point BigDecimal conversion#7819DarrenChangJR wants to merge 1 commit into
DarrenChangJR wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this PR does and why
TypeUtils.toBigDecimal(double)currently formats the binary value with theJSON number writer and parses that output as a
BigDecimal. The writerguarantees that parsing the text as a double recovers the same bits, but it can
choose a different decimal from
Double.toString.For example, converting
0.00054797Dreturns0.0005479699999999999instead of the canonical0.00054797returned byBigDecimal.valueOf, Fastjson1TypeUtils.castToBigDecimal, and Fastjson2'sown internal
Cast.toBigDecimal.The same path formats
NaNand infinities asnulland then attempts to parsethat token as a decimal, causing
NumberFormatException. Fastjson1 returnsnullfor those values.This change:
BigDecimal.valueOffor finite doubles;nullfor non-finite doubles and floats;Tests
TypeUtils, object conversion,JSONObject, andJSONArray;BigDecimal.valueOf;NaNand both infinities forfloatanddouble;branch.
中文说明
修改内容和原因
TypeUtils.toBigDecimal(double)目前先使用 JSON 数字 writer 输出字符串,再解析成
BigDecimal。该 writer 保证重新解析成 double 后二进制位一致,但不保证采用
Double.toString的规范十进制表示。例如
0.00054797D会得到0.0005479699999999999,而BigDecimal.valueOf、Fastjson1TypeUtils.castToBigDecimal以及 Fastjson2内部的
Cast.toBigDecimal都得到0.00054797。同一路径还会先把
NaN/ infinity 输出成null,随后把null当十进制解析,导致
NumberFormatException;Fastjson1 对这些值返回null。本修改对有限 double 使用
BigDecimal.valueOf,对非有限 double/float 直接返回
null,有限 float 则保留原有优化路径。测试包含 10,000 个固定随机 double 位模式、
JSONObject/JSONArray公开入口以及所有非有限值。clean 后完整 core 7,977 项测试均无失败;2,181 项兼容
矩阵的差异从 178 降至 174。