IEEEFloat32.cpp
Go to the documentation of this file.00001
00015 #include <algorithm>
00016 #include <cmath>
00017 #include <sstream>
00018
00019 #include <dlrNumeric/IEEEFloat32.h>
00020
00021 namespace dlr {
00022
00023 namespace numeric {
00024
00025
00026 IEEEFloat32::
00027 IEEEFloat32()
00028 : m_value(),
00029 m_bytes()
00030 {
00031 this->checkTypes();
00032 this->setValue(0.0);
00033 }
00034
00035
00036
00037
00038 IEEEFloat32::
00039 IEEEFloat32(FloatType value)
00040 : m_value(),
00041 m_bytes()
00042 {
00043 this->checkTypes();
00044 this->setValue(value);
00045 }
00046
00047
00048
00049
00050 IEEEFloat32::
00051 IEEEFloat32(unsigned char byte0,
00052 unsigned char byte1,
00053 unsigned char byte2,
00054 unsigned char byte3)
00055 : m_value(),
00056 m_bytes()
00057 {
00058 this->checkTypes();
00059 this->setValue(byte0, byte1, byte2, byte3);
00060 }
00061
00062
00063
00064 IEEEFloat32::
00065 IEEEFloat32(const IEEEFloat32& source)
00066 : m_value(source.m_value),
00067 m_bytes()
00068 {
00069 std::copy(&(source.m_bytes[0]), &(source.m_bytes[0]) + 4, &(m_bytes[0]));
00070 }
00071
00072
00073
00074
00075 unsigned char
00076 IEEEFloat32::
00077 getByte(size_t index0)
00078 {
00079
00080 if(index0 >= 4) {
00081 std::ostringstream message;
00082 message << "Index value, " << index0 << ", is out of bounds.";
00083 DLR_THROW(IndexException, "IEEEFloat32::getByte(size_t)",
00084 message.str().c_str());
00085 }
00086 return m_bytes[index0];
00087 }
00088
00089
00090
00091
00092 void
00093 IEEEFloat32::
00094 setValue(FloatType value)
00095 {
00096
00097 m_value = value;
00098
00099
00100
00101 if((value == 0.0) || (value == -0.0)) {
00102 m_bytes[0] = 0x00;
00103 m_bytes[1] = 0x00;
00104 m_bytes[2] = 0x00;
00105 m_bytes[3] = 0x00;
00106 } else {
00107
00108 this->floatToBinary(
00109 value, m_bytes[0], m_bytes[1], m_bytes[2], m_bytes[3]);
00110 }
00111 }
00112
00113
00114
00115
00116 void
00117 IEEEFloat32::
00118 setValue(unsigned char byte0,
00119 unsigned char byte1,
00120 unsigned char byte2,
00121 unsigned char byte3)
00122 {
00123
00124 m_bytes[0] = byte0;
00125 m_bytes[1] = byte1;
00126 m_bytes[2] = byte2;
00127 m_bytes[3] = byte3;
00128
00129
00130 if((byte0 == 0x00)
00131 && (byte1 == 0x00)
00132 && (byte2 == 0x00)
00133 && (byte3 == 0x00)) {
00134 m_value = 0.0;
00135 } else if((byte0 == 0x80)
00136 && (byte1 == 0x00)
00137 && (byte2 == 0x00)
00138 && (byte3 == 0x00)) {
00139
00140 m_bytes[0] = 0x00;
00141 m_value = 0.0;
00142 } else {
00143
00144 this->binaryToFloat(byte0, byte1, byte2, byte3, m_value);
00145 }
00146 }
00147
00148
00149
00150
00151
00152 void
00153 IEEEFloat32::
00154 binaryToFloat(unsigned char byte0,
00155 unsigned char byte1,
00156 unsigned char byte2,
00157 unsigned char byte3,
00158 IEEEFloat32::FloatType& value)
00159 {
00160
00161
00162
00163 int mantissaByte0 = static_cast<int>(byte1 | 0x80);
00164 int mantissaByte1 = static_cast<int>(byte2);
00165 int mantissaByte2 = static_cast<int>(byte3);
00166 int mantissaAsInt =
00167 (mantissaByte0 << 16) | (mantissaByte1 << 8) | mantissaByte2;
00168
00169
00170 if(byte0 & 0x80) {
00171 mantissaAsInt *= -1;
00172 }
00173
00174
00175 int exponentByte0 = static_cast<int>(byte0 & 0x7f);
00176 int exponentByte1 = static_cast<int>(byte1 & 0x80);
00177 int exponentAsInt = (exponentByte0 << 1) | (exponentByte1 >> 7);
00178
00179 exponentAsInt -= 127;
00180
00181
00182
00183
00184
00185
00186
00187 FloatType mantissa =
00188 static_cast<FloatType>(mantissaAsInt)
00189 / static_cast<FloatType>(std::pow(2.0, 23.0));
00190 value = mantissa * static_cast<FloatType>(
00191 std::pow(2.0, static_cast<double>(exponentAsInt)));
00192 }
00193
00194
00195
00196
00197
00198
00199 void
00200 IEEEFloat32::
00201 checkTypes()
00202 {
00203 if(sizeof(FloatType) < 4) {
00204 DLR_THROW(RunTimeException, "IEEEFloat32::checkTypes()",
00205 "FloatType has insufficient precision.");
00206 }
00207
00208
00209 }
00210
00211
00212
00213
00214 void
00215 IEEEFloat32::
00216 floatToBinary(FloatType value,
00217 unsigned char& byte0,
00218 unsigned char& byte1,
00219 unsigned char& byte2,
00220 unsigned char& byte3)
00221 {
00222
00223 if(value < 0.0) {
00224 byte0 = 0x80;
00225 value *= -1;
00226 } else {
00227 byte0 = 0x00;
00228 }
00229
00230
00231 int exponentAsInt = 0;
00232 while(value >= 2.0) {
00233 value /= 2.0;
00234 exponentAsInt += 1;
00235 }
00236 while(value < 1.0) {
00237 value *= 2.0;
00238 exponentAsInt -= 1;
00239 }
00240
00241
00242 exponentAsInt += 127;
00243
00244
00245 int mantissaAsInt = static_cast<int>(value * pow(2.0, 23));
00246
00247
00248 byte0 |= ((exponentAsInt & 0xfe) >> 1);
00249 byte1 = ((exponentAsInt & 0x01) << 7) | ((mantissaAsInt & 0x7f0000) >> 16);
00250 byte2 = ((mantissaAsInt & 0x00ff00) >> 8);
00251 byte3 = (mantissaAsInt & 0x0000ff);
00252 }
00253
00254 }
00255
00256 }