They both say that they are IEEE 754 compatible but I suspect that the
source is supplying floats to the '85 format and the java app is trying
to read them in the '92 format. Hell ensues.
Al though I don't have access to the IEEE specs, current or historical,
the doucmentation that I could dig up suggests that the standard
changed in the '92 version.
OK. Help!. What are my options here. Does anybody have a set of
converter classes they would like to donate? I really, really don't want
to write my own unless it is much more straightforward than I imagine.
--
Cheers, Des
Sent via Deja.com http://www.deja.com/
Before you buy.
I am not aware of any change in the formats. There could be small
changes in the edge cases that I wouldn't have noticed, but nothing that
would affect reading a file.
My first guess would be either a little-endian/big-endian problem or
other message format confusion. What bit pattern (e.g. in hex) do you
get if you try to send 1.0 to the Java program from the application?
Patricia
> I'm not able to dictate exactly what floats the application will return, but
> I can get it to issue a number that is approximately between 10 and 20.
>
> I get these bytes, in reverse network order: hex 41 88 58 81
> The problem is that the Java docs say that to calculate the exponent I have
> to do
> e - 150. Thus, there is no way I can just cast the app number onto a Java
> float.
Well... that seems to be just if you manually want to calculate the value. But
since all you care about is getting that float back, try this:
System.out.println( "[" + Float.intBitsToFloat( 0x41885881 ) + "]");
Then
byte[] raw = { (byte)0x41, (byte)0x88, (byte)0x58, (byte)0x81 };
int tmp = ( raw[0] << 24 )
| ( ( 0x0ff & raw[1] ) << 16 )
| ( ( 0x0ff & raw[2] ) << 8 )
| ( ( 0x0ff & raw[3] ) );
System.out.println( "0x" + Integer.toHexString( tmp ) + " = ["
+ Float.intBitsToFloat( tmp ) + "]");
--
"My new computer's got the clocks, it rocks
But it was obsolete before I opened the box" - W.A.Y.
I'm not able to dictate exactly what floats the application will return, but
I can get it to issue a number that is approximately between 10 and 20.
I get these bytes, in reverse network order: hex 41 88 58 81
Looking at the limited IEEE documentation that I have, I reckon that this
maps to
0100 0001 1000 1000 0101 1000 1000 0001
seee eeee emmm mmmm mmmm mmmm mmmm mmmm
s- sign, e- exponent, m- mantissa
so the exponent is 131(10000011) - 127 = 4
so the number is 2*4 x (1 + 0 + 0 + 0 + 0.0625) = about 17
So as far as I can see, the app is 754 compliant.
The problem is that the Java docs say that to calculate the exponent I have
to do
e - 150. Thus, there is no way I can just cast the app number onto a Java
float.
<paste from
http://java.sun.com/products/jdk/1.2/docs/api/java/lang/Float.html >
intBitsToFloat
public static float intBitsToFloat(int bits)
Returns the single-float corresponding to a given bit represention. The
argument is considered to be a representation of a floating-point value
according to the IEEE 754 floating-point "single precision" bit layout.
If the argument is 0x7f800000, the result is positive infinity.
If the argument is 0xff800000, the result is negative infinity.
If the argument is any value in the range 0x7f800001 through 0x7fffffff or
in the range 0xff800001 through 0xffffffff, the result is NaN. All IEEE 754
NaN values are, in effect, lumped together by the Java language into a
single value called NaN.
In all other cases, let s, e, and m be three values that can be computed
from the argument:
int s = ((bits >> 31) == 0) ? 1 : -1;
int e = ((bits >> 23) & 0xff);
int m = (e == 0) ?
(bits & 0x7fffff) << 1 :
(bits & 0x7fffff) | 0x800000;
Then the floating-point result equals the value of the mathematical
expression s·m·2e-150.
Parameters:
bits - an integer.
Returns:
the single-format floating-point value with the same bit pattern.
</paste >
What gives?
Help much appreciated,
Cheers, Des
Des Whewell wrote:
>
> Patricia Shanahan <pa...@acm.org> wrote in message
> news:38D05EF2...@acm.org...
> > I have the '85 printing of the standard, and the formats Java uses match
> > the single and double formats specified in it. The Java standard uses a
> > slightly different approach from IEEE 754 in how the formats are
> > described, but it comes down to the same thing.
...
>
> I'm not able to dictate exactly what floats the application will return, but
> I can get it to issue a number that is approximately between 10 and 20.
>
> I get these bytes, in reverse network order: hex 41 88 58 81
>
> Looking at the limited IEEE documentation that I have, I reckon that this
> maps to
>
> 0100 0001 1000 1000 0101 1000 1000 0001
> seee eeee emmm mmmm mmmm mmmm mmmm mmmm
>
> s- sign, e- exponent, m- mantissa
>
> so the exponent is 131(10000011) - 127 = 4
>
> so the number is 2*4 x (1 + 0 + 0 + 0 + 0.0625) = about 17
>
> So as far as I can see, the app is 754 compliant.
>
> The problem is that the Java docs say that to calculate the exponent I have
> to do
> e - 150. Thus, there is no way I can just cast the app number onto a Java
> float.
You should not cast to float, you should use Float.intBitsToFloat():
public class Test{
public static void main(String[] args){
float f = Float.intBitsToFloat(0x41885881);
System.out.println(f);
}
}
prints 17.043215
The issue of the different stated exponent bias is what I meant by a
difference in how the formats are described.
Look first at how the basic value is calculated. In the IEEE standard,
the 23 bit field that the JLS calls "mantissa" is the "fraction", with
the presumed binary point immediately to its left. In the JLS, the
binary point is treated as being immediately to the right of the
mantissa.
This causes the JLS to overvalue the significand by a factor of 2**23
compared to the IEEE standard. The JLS corrects for this by increasing
the stated exponent bias by 23, from 127 to 150. Increasing the bias by
23 reduces the net exponent by 23, and so results in undervaluing the
multiplier due to the exponent by a factor of 2**23. It's like the
difference between 17 and 1.7E1.
If you work your number though the JLS formulation you will come to the
same final answer. It is ONLY a difference in how the two standards
describe the same format.
Patricia
<cut>
>
> You should not cast to float, you should use Float.intBitsToFloat():
noted.
<cut>
> This causes the JLS to overvalue the significand by a factor of 2**23
> compared to the IEEE standard. The JLS corrects for this by increasing
> the stated exponent bias by 23, from 127 to 150. Increasing the bias by
> 23 reduces the net exponent by 23, and so results in undervaluing the
> multiplier due to the exponent by a factor of 2**23. It's like the
> difference between 17 and 1.7E1.
<Clouds roll back, light shines through>
ahhhhhhhhhh! :-)
</Clouds roll back, light shines through>
I've now got the code working, thanks everyone. Much appreciated.
Cheers, Des