00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020 #ifndef SHHALFALIMPL_HPP
00021 #define SHHALFALIMPL_HPP
00022
00023 #include <iostream>
00024 #include <cmath>
00025 #include "ShMath.hpp"
00026 #include "ShHalf.hpp"
00027
00028 namespace SH {
00029
00030 inline
00031 ShHalf::ShHalf()
00032 {}
00033
00034 inline
00035 ShHalf::ShHalf(double value)
00036 : m_val(to_val(value))
00037 {
00038 }
00039
00040 inline
00041 ShHalf::operator double() const
00042 {
00043 return get_double();
00044 }
00045
00046
00048 inline
00049 ShHalf& ShHalf::operator=(double value)
00050 {
00051 m_val = to_val(value);
00052 return *this;
00053 }
00054
00055 inline
00056 ShHalf& ShHalf::operator=(const ShHalf& other)
00057 {
00058 m_val = other.m_val;
00059 return *this;
00060 }
00061
00062 inline
00063 ShHalf& ShHalf::operator+=(double value)
00064 {
00065 set_val(get_double() + value);
00066 return *this;
00067 }
00068
00069 inline
00070 ShHalf& ShHalf::operator+=(const ShHalf& other)
00071 {
00072 set_val(get_double() + other.get_double());
00073 return *this;
00074 }
00075
00076 inline
00077 ShHalf& ShHalf::operator-=(double value)
00078 {
00079 set_val(get_double() - value);
00080 return *this;
00081 }
00082
00083 inline
00084 ShHalf& ShHalf::operator-=(const ShHalf& other)
00085 {
00086 set_val(get_double() - other.get_double());
00087 return *this;
00088 }
00089
00090 inline
00091 ShHalf& ShHalf::operator*=(double value)
00092 {
00093 set_val(get_double() * value);
00094 return *this;
00095 }
00096
00097 inline
00098 ShHalf& ShHalf::operator*=(const ShHalf& other)
00099 {
00100 set_val(get_double() * other.get_double());
00101 return *this;
00102 }
00103
00104 inline
00105 ShHalf& ShHalf::operator/=(double value)
00106 {
00107 set_val(get_double() / value);
00108 return *this;
00109 }
00110
00111 inline
00112 ShHalf& ShHalf::operator/=(const ShHalf& other)
00113 {
00114 set_val(get_double() / other.get_double());
00115 return *this;
00116 }
00117
00118 inline
00119 ShHalf& ShHalf::operator%=(double value)
00120 {
00121 set_val(std::fmod(get_double(), value));
00122 return *this;
00123 }
00124
00125 inline
00126 ShHalf& ShHalf::operator%=(const ShHalf& other)
00127 {
00128 set_val(std::fmod(get_double(), other.get_double()));
00129 return *this;
00130 }
00131
00133 inline
00134 ShHalf ShHalf::operator-() const
00135 {
00136
00137 T result = m_val ^ S;
00138 return make_half(result);
00139 }
00140
00141 inline
00142 std::ostream& operator<<(std::ostream &out, const ShHalf &value)
00143 {
00144 out << double(value);
00145 return out;
00146 }
00147
00148 inline
00149 std::istream& operator>>(std::istream &in, ShHalf &value)
00150 {
00151 double temp;
00152 in >> temp;
00153 value = temp;
00154 return in;
00155 }
00156
00157 inline
00158 ShHalf ShHalf::make_half(T value)
00159 {
00160 ShHalf result;
00161 result.m_val = value;
00162 return result;
00163 }
00164
00165 inline
00166 ShHalf::T ShHalf::to_val(double value) {
00167 int exponent;
00168 double fraction = frexp(value, &exponent);
00169 short sign = fraction < 0;
00170 fraction = sign ? -fraction : fraction;
00171 T result;
00172
00173
00174
00175 result = (sign << 15);
00176 if(fraction == 0) {
00177 } else if(fabs(value) > 65504) {
00178 result |= 31 << 10;
00179 } else if(exponent < -13) {
00180 int significand = (int)(fraction * (1LL << (exponent + 24)));
00181 result |= significand;
00182 } else {
00183 int significand = (int)((fraction - 0.5) * (1 << 11));
00184 result |= ((exponent + 14) << 10) | significand;
00185 }
00186 return result;
00187 }
00188
00189 inline
00190 void ShHalf::set_val(double value) {
00191 m_val = to_val(value);
00192 }
00193
00194 inline
00195 double ShHalf::get_double() const {
00196
00197 short sign = -((m_val >> 14) & 2) + 1;
00198 short exponent = (m_val >> 10) & 0x1F;
00199 short significand = m_val & 0x3FF;
00200 double fraction = sign * ((exponent ? 1 : 0) + significand / (double)(1 << 10));
00201
00202 return ldexp(fraction, (exponent ? exponent - 15 : -14));
00203 }
00204
00205 }
00206
00207 #endif