Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java struts2 weird serialization behavior (rounds big numbers by its self)

i've the next isolated test case scenario

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

this is the action at 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,

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)

so, its this an struts2 bug??

greetings,

like image 363
Lu15_CL4 Avatar asked Mar 03 '26 05:03

Lu15_CL4


1 Answers

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.

For example, in 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.

like image 91
Jim Garrison Avatar answered Mar 05 '26 19:03

Jim Garrison



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!