سؤال

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,

هل كانت مفيدة؟

المحلول

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top