Why does converting in and out of LongBits introduce error?

조회 수: 5 (최근 30일)
Alec Jacobson
Alec Jacobson 2022년 11월 25일
답변: Aditya 2022년 11월 28일
In Java,
double value = 0.007168281523489443;
double res = java.lang.Double.longBitsToDouble(java.lang.Double.doubleToLongBits(value));
System.out.println(value==res);
prints true
But the same thing in matlab,
value = 0.007168281523489443;
res = java.lang.Double.longBitsToDouble(java.lang.Double.doubleToLongBits(value));
res == value
shows
ans =
logical
0
I noticed that class(java.lang.Double.doubleToLongBits(value)) is 'double'. I would have thought it would be uint64. Could this be related?
  댓글 수: 1
Alec Jacobson
Alec Jacobson 2022년 11월 25일
FWIW,
typecast(typecast(value,'uint64'),'double') == value
works

댓글을 달려면 로그인하십시오.

답변 (1개)

Aditya
Aditya 2022년 11월 28일
Hi,
I understand that you are using java.long.Double to convert a double to its IEEE-754 representation as long and the long representation back to a double. Finally, you are comparing both the doubles to check if they are equal or not. When using Java, the equality is true but when calling the same functions from MATLAB, the equality results in a false.
If a Java method returns a primitive type, MATLAB converts the type. When a long is retuned from a Java method, it is converted to a double’. You can read more about it at Handle Data Returned from Java Methods - MATLAB & Simulink (mathworks.com).
So, when java.lang.Double.doubleToLongBits is called, its returned ‘long’ value is converted to a ‘double.’ This ‘double’ value, when passed to java.lang.Double.longBitsToDouble, will again be converted to a long.’ During these two conversions, there is a loss of information which leads equality comparison resulting in false. Equivalent Java code for MATLAB calls would be something like this:
double original_double = 0.007168281523489443;
long original_long = java.lang.Double.doubleToLongBits(original_double);
double long_to_double = (double)original_long;
long double_to_long = (long) long_to_double;
System.out.println(String.format("Original long representation: 0x%08X", original_long));
System.out.println(String.format("Representation after two conversions: 0x%08X", double_to_long));
double converted = java.lang.Double.longBitsToDouble(double_to_long);
boolean comparison = converted == original_double;
System.out.println("Comparing original and converted: " + comparison);
You can see that the comparison evaluates to a false in the output of above code:
Original long representation: 0x3F7D5C7CEB63F9DE
Representation after two conversions: 0x3F7D5C7CEB63FA00
Comparing original and converted: false
Also notice the difference is representation of long and a two-times converted long (long to double to long).
Therefore, when comparing floating points, instead of using ‘==,’ you should always use a small tolerance as shown here. The value of tolerance would depend on your use case.

카테고리

Help CenterFile Exchange에서 Mathematics에 대해 자세히 알아보기

태그

제품


릴리스

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by