72 static_assert(((int(sFMT::mbits) >= int(dFMT::mbits)) &&
73 (
int(sFMT::ebits) >= int(dFMT::ebits)))
74 || ((int(sFMT::mbits) <= int(dFMT::mbits)) &&
75 (
int(sFMT::ebits) <= int(dFMT::ebits))));
80 if (
int(sFMT::mbits) >= int(dFMT::mbits) &&
81 int(sFMT::ebits) >= int(dFMT::ebits)) {
87 if (std::numeric_limits<dFMT>::has_quiet_NaN) {
88 out = std::numeric_limits<dFMT>::quiet_NaN();
90 out = std::numeric_limits<dFMT>::max();
94 if (std::numeric_limits<dFMT>::has_infinity) {
95 out = std::numeric_limits<dFMT>::infinity();
97 out = std::numeric_limits<dFMT>::max();
99 }
else if (in.mant == 0 && in.exp == 0) {
106 uint32_t mant = in.mant &
mask(sFMT::mbits);
107 int32_t exp = in.exp - sFMT::bias + dFMT::bias;
112 mant |= (1 << sFMT::mbits);
115 mant >>= (sFMT::mbits - dFMT::mbits);
126 mant &=
mask(dFMT::mbits);
145 if (
int(sFMT::mbits) >
int(dFMT::mbits)
147 bool round_up =
false;
149 int check_shift = sFMT::mbits - dFMT::mbits - 1;
150 uint32_t check_mant = in.mant &
mask(sFMT::mbits);
152 check_mant >>= check_shift;
156 check_mant = in.mant >> (sFMT::mbits - dFMT::mbits);
167 int check_bit = 1 << -exp;
168 round_up = (check_mant & check_bit);
171 round_up = (check_mant & 0x1);
178 int sticky = in.mant &
mask(sFMT::mbits - dFMT::mbits);
179 if (round_up && !sticky) {
180 if (!(out.mant & 1)) {
186 if (out.mant ==
mask(dFMT::mbits)) {
188 if (out.exp !=
mask(dFMT::ebits)) {
196 }
else if (
int(sFMT::mbits) >
int(dFMT::mbits)
203 uint32_t discarded = in.mant &
mask(sFMT::mbits - dFMT::mbits);
204 uint32_t max_mant =
mask(sFMT::mbits);
206 float round_prob = float(discarded) / float(max_mant);
211 auto srFunc = [](uint32_t in) {
212 uint32_t bit = (in ^ (in >> 1) ^ (in >> 3) ^ (in >> 12));
213 return (in >> 1) | (bit << 15);
218 float draw_prob = float(srFunc(seed))
219 / float(std::numeric_limits<uint32_t>::max());
224 if (round_prob >= draw_prob) {
225 if (out.mant ==
mask(dFMT::mbits)) {
227 if (out.exp !=
mask(dFMT::ebits)) {
237 }
else if (
int(sFMT::mbits) <=
int(dFMT::mbits) &&
238 int(sFMT::ebits) <=
int(dFMT::ebits)) {
244 if (std::numeric_limits<dFMT>::has_quiet_NaN) {
245 out = std::numeric_limits<dFMT>::quiet_NaN();
247 out = std::numeric_limits<dFMT>::max();
251 if (std::numeric_limits<dFMT>::has_infinity) {
252 out = std::numeric_limits<dFMT>::infinity();
254 out = std::numeric_limits<dFMT>::max();
256 }
else if (in.mant == 0 && in.exp == 0) {
262 out.mant = in.mant << (dFMT::mbits - sFMT::mbits);
263 out.exp = in.exp + dFMT::bias - sFMT::bias;
267 if (!in.exp &&
int(sFMT::ebits) != int(dFMT::ebits)) {
268 uint32_t
m = out.mant;
271 while (!(
m >> dFMT::mbits)) {
275 out.mant =
m &
mask(dFMT::mbits);
277 }
else if (!in.exp) {
280 uint32_t
m = out.mant;
282 out.mant =
m &
mask(dFMT::mbits);