001: /*
002: * Copyright 2003 (C) TJDO.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the TJDO License version 1.0.
006: * See the terms of the TJDO License in the documentation provided with this software.
007: *
008: * $Id: FloatWidget.java,v 1.4 2003/02/25 06:55:16 jackknifebarber Exp $
009: */
010:
011: package com.triactive.jdo.test;
012:
013: public class FloatWidget extends Widget {
014: /**
015: * The minimum accuracy required of the storage and retrieval of float
016: * values.
017: * 1e-6 indicates that values must retain at least six significant digits
018: * of accuracy.
019: */
020: public static final float FLOAT_EPSILON = 1e-5f;
021:
022: /**
023: * The minimum accuracy required of the storage and retrieval of double
024: * values.
025: * 1e-14 indicates that values must retain at least 14 significant digits
026: * of accuracy.
027: */
028: public static final double DOUBLE_EPSILON = 1e-14d;
029:
030: /**
031: * The minimum float value we will try to store in the DB.
032: * This is set to roughly half of the Java limit.
033: */
034: public static final float MIN_FLOAT_VALUE = 1e-22f;
035:
036: /**
037: * The maximum float value we will try to store in the DB.
038: * This is set to roughly half of the Java limit.
039: */
040: public static final float MAX_FLOAT_VALUE = 1e17f;
041:
042: /**
043: * The minimum double value we will try to store in the DB.
044: * This is set to roughly half of the Java limit.
045: */
046: public static final double MIN_DOUBLE_VALUE = 1e-62d;
047:
048: /**
049: * The maximum double value we will try to store in the DB.
050: * This is set to roughly half of the Java limit.
051: */
052: public static final double MAX_DOUBLE_VALUE = 1e62d;
053:
054: private float floatField;
055: private Float floatObjField;
056: private double doubleField;
057: private Double doubleObjField;
058:
059: public FloatWidget() {
060: super ();
061: }
062:
063: public float getFloatField() {
064: return floatField;
065: }
066:
067: public Float getFloatObjField() {
068: return floatObjField;
069: }
070:
071: public double getDoubleField() {
072: return doubleField;
073: }
074:
075: public Double getDoubleObjField() {
076: return doubleObjField;
077: }
078:
079: private float nextFloat() {
080: float f;
081:
082: do {
083: f = Float.intBitsToFloat(r.nextInt());
084: } while (Float.isNaN(f) || Float.isInfinite(f)
085: || f < MIN_FLOAT_VALUE || f > MAX_FLOAT_VALUE);
086:
087: return f;
088: }
089:
090: private double nextDouble() {
091: double d;
092:
093: do {
094: d = Double.longBitsToDouble(r.nextLong());
095: } while (Double.isNaN(d) || Double.isInfinite(d)
096: || d < MIN_DOUBLE_VALUE || d > MAX_DOUBLE_VALUE);
097:
098: return d;
099: }
100:
101: /**
102: * Fills all of the object's fields with random data values. Any non-
103: * primitive fields (with the exception of <code>id</code>) will also be
104: * assigned <code>null</code> on a random basis.
105: */
106:
107: public void fillRandom() {
108: super .fillRandom();
109:
110: floatField = nextFloat();
111: floatObjField = nextNull() ? null : new Float(nextFloat());
112: doubleField = nextDouble();
113: doubleObjField = nextNull() ? null : new Double(nextDouble());
114: }
115:
116: /**
117: * Indicates whether some other object is "equal to" this one. By comparing
118: * against an original copy of the object, <code>compareTo()</code> can be
119: * used to verify that the object has been written to a database and read
120: * back correctly.
121: *
122: * @param obj the reference object with which to compare
123: *
124: * @return <code>true</code> if this object is equal to the obj argument;
125: * <code>false</code> otherwise.
126: */
127:
128: public boolean compareTo(Object obj) {
129: if (obj == this )
130: return true;
131:
132: if (!(obj instanceof FloatWidget) || !super .compareTo(obj))
133: return false;
134:
135: FloatWidget w = (FloatWidget) obj;
136:
137: if (floatObjField == null) {
138: if (w.floatObjField != null)
139: return false;
140: } else if (!approximates(floatObjField.floatValue(),
141: w.floatObjField.floatValue()))
142: return false;
143:
144: if (doubleObjField == null) {
145: if (w.doubleObjField != null)
146: return false;
147: } else if (!approximates(doubleObjField.doubleValue(),
148: w.doubleObjField.doubleValue()))
149: return false;
150:
151: return approximates(floatField, w.floatField)
152: && approximates(doubleField, w.doubleField);
153: }
154:
155: public static boolean approximates(float x, float y) {
156: return Math.abs(x - y)
157: / Math.max(Math.max(Math.abs(x), Math.abs(y)),
158: Float.MIN_VALUE) < FLOAT_EPSILON;
159: }
160:
161: public static boolean approximates(double x, double y) {
162: return Math.abs(x - y)
163: / Math.max(Math.max(Math.abs(x), Math.abs(y)),
164: Double.MIN_VALUE) < DOUBLE_EPSILON;
165: }
166:
167: /**
168: * Returns a string representation for this object. All of the field
169: * values are included in the string for debugging purposes.
170: *
171: * @return a string representation for this object.
172: */
173:
174: public String toString() {
175: StringBuffer s = new StringBuffer(super .toString());
176:
177: s.append(" floatField = ").append(floatField);
178: s.append('\n');
179: s.append(" floatObjField = ").append(floatObjField);
180: s.append('\n');
181: s.append(" doubleField = ").append(doubleField);
182: s.append('\n');
183: s.append(" doubleObjField = ").append(doubleObjField);
184: s.append('\n');
185:
186: return s.toString();
187: }
188: }
|