com.ibm.as400.access.NPAttrFloat Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400 Show documentation
Show all versions of jt400 Show documentation
The Open Source version of the IBM Toolbox for Java
The newest version!
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: NPAttrFloat.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2000 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
/**
* For a list of valid attribute IDs, see the NPObject class.
**/
class NPAttrFloat extends NPAttribute implements Cloneable,
java.io.Serializable
{
private static final String copyright = "Copyright (C) 1997-2000 International Business Machines Corporation and others.";
static final long serialVersionUID = 4L;
//
// we are always dealing with packed 15,5 numbers so just make these
// static constants. If we ever have to deal with other types of packed
// numbers we can make these variables and change them on the constructor
// based on the attribute ID and the conversion code should still work.
//
private static final int DIGITS = 15;
private static final int DECIMALPT = 5;
private float attrValue_; // stored float value in PC terms
NPAttrFloat(NPAttrFloat attr)
{
super(attr);
attrValue_ = attr.attrValue_;
}
NPAttrFloat(int ID)
{
super(ID, FLOAT);
}
NPAttrFloat(int ID, float value)
{
super(ID, FLOAT);
set(value);
}
NPAttrFloat(int ID,
byte[] hostDataStream,
int offset,
int length)
{
super(ID, FLOAT, hostDataStream, offset, length, null);
buildFloatFromHostData();
}
/** buildHostData - builds the PACKED 15,5 byte data from the float value
**/
private void buildHostData()
{
byte[] hostValue; // array to hold our packed decimal number
int position; // position goes from -decimalPt to +(digits-decimalPt).
int digit; // value of the digit we are on
int needed; // number of bytes needed
int byteIndex; // current byte
boolean fHighNibble; // current nibble (high or low)
double MyNumber; // working copy of the float number
double mult;
// I have to add a fraction to the number because of rounding errors. If I don't do this
// then if you say
// double x = 12.657; (for example)
// unsigned y = (unsigned)x*1000;
// y will be 12656 - not what I want! So, I say y = (unsigned)((x+.0001)*1000) and that
// works. I think this is because 12.657 may really not be exactly that, internally
// it may be 12.656999999 is as close as the machine can get to 12.657.
MyNumber = Math.abs(attrValue_); // work with the positive number
MyNumber += 0.000001; // fix any rounding errors
// find out how many bytes are need to hold this guy
// needed = (unsigned)((((float)digits+1)/2)+0.5);
needed = (int)((((float)DIGITS+1)/2)+0.5); // should be 8
byteIndex = needed - 1; // start with the last byte
hostValue = new byte[needed]; // allocate host byte array
// mult is the multplier you need to get the current digit (we start with the least
// significant one) into the 1's column of the number - we then use a cast to integer
// to drop the fractional part of the number and a %10 to drop the part of the number
// that is 10 or over (that's how we get this one digit).
//
// if you have a packed decimal(11,3), mult would start at 1000 and go to
// 1x10**(-8) when you finished the for loop.
mult = Math.pow(10, DECIMALPT);
// First put the sign nibble in the lowest order nibble.
// 0x0F = positive
// 0x0D = negative
if (attrValue_ < 0) // if this number is negative
{
hostValue[byteIndex] = 0x0D; // negative sign
} else {
hostValue[byteIndex] = 0x0F; // positive sign
} /* endif */
// fHighNibble indicates which half-byte we're working on.
// We started with the low nibble and used it for the sign,
// now we're on the high nibble.
fHighNibble = true; // go to high order nibble
for (position = -DECIMALPT; position < (DIGITS - DECIMALPT) ; position++ )
{
digit = (int)(MyNumber*mult) % 10;
mult /= 10;
if (!fHighNibble)
{
hostValue[byteIndex] = (byte)digit; // put it in the low nibble (and zero the high)
} else {
hostValue[byteIndex] |= (byte)digit << 4; // mask it in on the high nibble.
byteIndex--; // go to next byte.
} /* endif */
fHighNibble = !fHighNibble;
} /* endfor */
super.setHostData(hostValue, null); // @B1C
}
// sets the value of attrValue_ based on the current super's host data array
private void buildFloatFromHostData()
{
int needed = (int)((((float)DIGITS+1)/2)+0.5); // should be 8 for us
int i, j;
double mult;
boolean fHighNibble; // current nibble (high or low)
byte[] hostData; // packed 15,5 number
int byteIndex; // index into hostData array
attrValue_ = 0.0F;
hostData = super.getHostData(null); // @B1C
if (hostData != null)
{
byteIndex = 0;
mult = Math.pow(10.0,(double)DIGITS-(double)DECIMALPT-1);
// we should ALWAYS end the loop with fHighNibble == FALSE
// if digits is ODD
// start with high nibble of first byte
// else
// there is a wasted nibble, so start with low nibble of first byte
if ((DIGITS%2) != 0)
{
fHighNibble = true;
} else {
fHighNibble = false;
} /* endif */
for (i=0; i < DIGITS; i++)
{
if (fHighNibble)
{
j = (int)(hostData[byteIndex]) >> 4; // get high nibble
j = j & 0x0F; // mask hi order @B3
// so int is signed correctly.
} else {
j = (int)(hostData[byteIndex]) & 0x0F; // get low nibble
byteIndex++;
} /* endif */
fHighNibble = !fHighNibble;
// should we check j to be >= 0 && <= 9 here?
attrValue_ += j*(float)mult;
mult /= 10.0;
} /* endfor */
// put a sign on number
// if low order nibble of *pBuf is 0x0D
// number is negative
// else
// number is positive (low nibble should be 0x0F)
j = (int)(hostData[byteIndex]) & 0x0F;
if (j == 0x0D)
{
attrValue_ *= -1.0;
} /* endif */
} /* endif - hostData == NULL */
}
protected Object clone()
{
NPAttrFloat attr;
attr = new NPAttrFloat(this);
return attr;
}
float get()
{
return attrValue_;
}
void set(float value)
{
attrValue_ = value;
buildHostData();
}
void setHostData(byte[] data, ConverterImpl converter) // @B1C
{
super.setHostData(data, converter); // @B1C
buildFloatFromHostData();
}
} // end of class NPAttrFloat
© 2015 - 2025 Weber Informatics LLC | Privacy Policy