aboutsummaryrefslogtreecommitdiff
path: root/java/com/xagasoft/gats/GatsFloat.java
blob: d70f9102d0561d9385c6ba2d8ba924f3b727b994 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package com.xagasoft.gats;

import java.io.InputStream;
import java.io.DataInputStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;

import java.lang.Math;

public class GatsFloat extends GatsObject
{
	double dValue = 0.0;

	public GatsFloat()
	{
	}

	public GatsFloat( double dValue )
	{
		this.dValue = dValue;
	}

	public double getValue()
	{
		return dValue;
	}

	public void setValue( double dValue )
	{
		this.dValue = dValue;
	}

	public String toString()
	{
		return "" + dValue;
	}

	public int getType()
	{
		return GatsObject.FLOAT;
	}

	public void read( InputStream is, char cType ) throws java.io.IOException
	{
		if( cType == 'F' )
		{
			char cSubType = (char)is.read();
			switch( cSubType )
			{
				case 'N': dValue = -Double.NaN;					break;
				case 'n': dValue = Double.NaN;					break;
				case 'I': dValue = Double.NEGATIVE_INFINITY;	break;
				case 'i': dValue = Double.POSITIVE_INFINITY;	break;
				case 'Z': dValue = -0.0;						break;
				case 'z': dValue = 0.0;							break;
			}
		}
		else if( cType == 'f' )
		{
			int iStr = (int)GatsInteger.readPackedInt( is );
			boolean bNeg = false;
			if( iStr < 0 )
			{
				bNeg = true;
				iStr = -iStr;
			}
			int aBuf[] = new int[iStr];
			DataInputStream dis = new DataInputStream( is );
			for( int j = 0; j < iStr; j++ )
			{
				aBuf[j] = dis.readUnsignedByte();
			}
			dValue = 0.0;
			for( int j = iStr-1; j > 0; j-- )
			{
				dValue = (dValue+(double)aBuf[j])*0x1p-8;
			}
			dValue += aBuf[0];
			long iScale = GatsInteger.readPackedInt( is );
			dValue *= Math.pow( 256.0, iScale );
			if( bNeg )
				dValue = -dValue;
		}
	}

	public void write( OutputStream os ) throws java.io.IOException
	{
		if( dValue == 0.0 )
		{
			os.write( (int)'F' );
			os.write( (int)'z' );
		}
		else if( Double.isInfinite( dValue ) )
		{
			os.write( (int)'F' );
			if( dValue < 0 )
				os.write( (int)'I' );
			else
				os.write( (int)'i' );
		}
		else if( Double.isNaN( dValue ) )
		{
			os.write( (int)'F' );
			os.write( (int)'n' );
		}
		else
		{
			os.write( (int)'f' );
			double d = dValue;
			boolean bNeg = false;
			if( d < 0.0 )
			{
				bNeg = true;
				d = -d;
			}
			
			ByteArrayOutputStream oTmp = new ByteArrayOutputStream();
			long iScale = (long)(Math.log( d ) / 0x1.62e42fefa39efp+2);
			if( iScale < 0 ) iScale--;
			d /= Math.pow( 256.0, iScale );
			oTmp.write( (int)d );
			d -= (int)d;
			for( int j = 0; j < 150 && d != 0.0; j++ )
			{
				d = d*256.0;
				oTmp.write( (int)d );
				d -= (int)d;
			}
			if( bNeg )
				GatsInteger.writePackedInt( os, -oTmp.size() );
			else
				GatsInteger.writePackedInt( os, oTmp.size() );
			os.write( oTmp.toByteArray() );
			GatsInteger.writePackedInt( os, iScale );
		}
	}
};