java struts2奇怪的序列化行为(由自己舍入大数字)

时间:2022-07-19 16:52:23

i've the next isolated test case scenario

我是下一个孤立的测试案例场景

@SMDMethod
public BigInteger getSomeReallyBigInteger() {
    return new BigInteger("154456875042019001");
}

this is the action at struts.xml

这是struts.xml上的操作

    <action name="DataSourceRpc" class="isoblock.struts2.action.DataSourceAction" method="smd">
        <interceptor-ref name="json">
            <param name="enableSMD">true</param> 
        </interceptor-ref>
        <result type="json">
            <param name="enableSMD">true</param>
        </result>
    </action>

im calling the SMD function using a JSON-RPC implentation (using dojo-rpc), this is the failure,

我使用JSON-RPC实现(使用dojo-rpc)调用SMD函数,这是失败,

when i call the last function the result callback its:

当我调用最后一个函数时,结果回调它:

  • 154456875042019000

instead of

  • 154456875042019001

this happens only with big numbers (all with 17 or more dijits), im using struts2-json-plugin-2.3.8.jar (latest)

这种情况只发生在大数字(全部有17个或更多dijit),我使用struts2-json-plugin-2.3.8.jar(最新)

so, its this an struts2 bug??

那么,这是一个struts2错误?

greetings,

1 个解决方案

#1


2  

The problem is that numbers in Javascript are double-precision floats, which cannot represent 154456875042019001 accurately. Double-precision floats have 15-17 digits of precision and you have 18 digits. When converted to a float and back again some precision is lost.

问题是Javascript中的数字是双精度浮点数,不能准确表示154456875042019001。双精度浮点数具有15-17位精度,您有18位数。当转换为浮动并再次返回时,会丢失一些精度。

For example, in Perl:

例如,在Perl中:

$a=154456875042019001.0;
printf "%20d",$a;

outputs

154456875042019008

Further details:

The hexadecimal representation of 15445687504201900110 is 0x0224bdb5a1ff16b9, which contains 58 significant bits (in binary it starts 0000 0010 0010 0100 ..., so 64 minus 6 leading zero bits). Double-precision float has 52 bits of precision, so some bits are lost when converting the 64-bit long to the double.

15445687504201900110的十六进制表示为0x0224bdb5a1ff16b9,其包含58个有效位(以二进制形式,它开始于0000 0010 0010 0100 ...,因此64减去6个前导零位)。双精度浮点数具有52位精度,因此在将64位长整数转换为双精度时会丢失一些位。

#1


2  

The problem is that numbers in Javascript are double-precision floats, which cannot represent 154456875042019001 accurately. Double-precision floats have 15-17 digits of precision and you have 18 digits. When converted to a float and back again some precision is lost.

问题是Javascript中的数字是双精度浮点数,不能准确表示154456875042019001。双精度浮点数具有15-17位精度,您有18位数。当转换为浮动并再次返回时,会丢失一些精度。

For example, in Perl:

例如,在Perl中:

$a=154456875042019001.0;
printf "%20d",$a;

outputs

154456875042019008

Further details:

The hexadecimal representation of 15445687504201900110 is 0x0224bdb5a1ff16b9, which contains 58 significant bits (in binary it starts 0000 0010 0010 0100 ..., so 64 minus 6 leading zero bits). Double-precision float has 52 bits of precision, so some bits are lost when converting the 64-bit long to the double.

15445687504201900110的十六进制表示为0x0224bdb5a1ff16b9,其包含58个有效位(以二进制形式,它开始于0000 0010 0010 0100 ...,因此64减去6个前导零位)。双精度浮点数具有52位精度,因此在将64位长整数转换为双精度时会丢失一些位。