1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: ut_Float24.h 4 5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Revision: 24277 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NW_UT_FLOAT24_H_ 17 #define NW_UT_FLOAT24_H_ 18 19 #include <nw/ut/ut_Inlines.h> 20 #include <nw/math/math_Types.h> 21 22 namespace nw { 23 namespace ut { 24 25 //-------------------------------------------------------------------------- 26 //! @brief 32bit 浮動小数用のユーティリティです。 27 // 28 // 32bit 浮動小数のビットフォーマットは次の通りです。 29 // | sign | exponent | fraction | 30 // sign : 符号 1 bit. 31 // exponent : 指数部 8 bit. bias 127. 32 // fraction : 仮数部 23 bit. 33 //--------------------------------------------------------------------------- 34 class Float32 35 { 36 public: 37 //-------------------------------------------------------------------------- 38 //! @brief f32 から 32bit 浮動小数のビット表現に変換します。 39 //! 40 //! @param[in] value 32bit float の値です。 41 //! 42 //! @return 32bit 浮動小数のビット表現を返します。 43 //-------------------------------------------------------------------------- Float32ToBits32(f32 value)44 static u32 Float32ToBits32(f32 value) 45 { 46 return *reinterpret_cast<u32*>(&value); 47 } 48 49 //-------------------------------------------------------------------------- 50 //! @brief 32bit 浮動小数のビット表現から f32 に変換します。 51 //! 52 //! @param[in] value 32bit 浮動小数のビット表現です。 53 //! 54 //! @return f32 の値です。 55 //-------------------------------------------------------------------------- Bits32ToFloat32(u32 value)56 static f32 Bits32ToFloat32(u32 value) 57 { 58 return *reinterpret_cast<f32*>(&value); 59 } 60 }; 61 62 //-------------------------------------------------------------------------- 63 //! @brief 24bit 浮動小数用のユーティリティです。 64 // 65 // 24bit 浮動小数のビットフォーマットは次の通りです。 66 // | sign | exponent | fraction | 67 // sign : 符号 1 bit. 68 // exponent : 指数部 7 bit. bias 63. 69 // fraction : 仮数部 16 bit. 70 //--------------------------------------------------------------------------- 71 class Float24 72 { 73 public: 74 //-------------------------------------------------------------------------- 75 //! @brief デフォルトコンストラクタです。 76 //-------------------------------------------------------------------------- Float24()77 Float24() : m_Float32( 0.0f ) {} 78 79 //-------------------------------------------------------------------------- 80 //! @brief コンストラクタです。 81 //! 82 //! @param[in] bits24 24bit 浮動小数のビットを表現した整数値です。 83 //-------------------------------------------------------------------------- Float24(u32 bits24)84 /* implicit */ Float24( u32 bits24 ) 85 { 86 m_Float32 = Bits24ToFloat32( bits24 ); 87 } 88 89 //-------------------------------------------------------------------------- 90 //! @brief コンストラクタです。 91 //! 92 //! @param[in] value 32bit 浮動小数の値から 24bit float を生成します。 93 //-------------------------------------------------------------------------- Float24(f32 value)94 /* implicit */ Float24( f32 value ) : m_Float32( value ) {} 95 GetFloat32Value()96 f32 GetFloat32Value() const { return m_Float32; } GetFloat24Value()97 u32 GetFloat24Value() const { return Float32ToBits24( m_Float32 ); } 98 99 Float24& operator =(f32 value) { this->m_Float32 = value; return *this; } 100 Float24& operator =(u32 bits24) { this->m_Float32 = Bits24ToFloat32( bits24 ); return *this; } 101 f32()102 operator f32() const { return m_Float32; } 103 104 f32 operator +(f32 right) const { return this->m_Float32 + right; } 105 f32 operator -(f32 right) const { return this->m_Float32 - right; } 106 f32 operator *(f32 right) const { return this->m_Float32 * right; } 107 f32 operator /(f32 right) const { return this->m_Float32 / right; } 108 109 Float24& operator +=(f32 rhs) { this->m_Float32 += rhs; return *this; } 110 Float24& operator -=(f32 rhs) { this->m_Float32 -= rhs; return *this; } 111 Float24& operator *=(f32 rhs) { this->m_Float32 *= rhs; return *this; } 112 Float24& operator /=(f32 rhs) { this->m_Float32 /= rhs; return *this; } 113 114 bool operator ==(f32 rhs) const { return (rhs == this->m_Float32); } 115 bool operator !=(f32 rhs) const { return !(*this == rhs); } 116 117 //-------------------------------------------------------------------------- 118 //! @brief 24bit float から 32bit float に変換します。 119 //! 120 //! @param[in] bits24 24bit 浮動小数のビットを表現した整数値です。 121 //! 122 //! @return f32 に変換した値を返します。 123 //-------------------------------------------------------------------------- Bits24ToFloat32(u32 bits24)124 static f32 Bits24ToFloat32(u32 bits24) 125 { 126 u32 sign = bits24 & SIGN24; 127 int exp = (int)((bits24 & EXP_MASK24) >> FRACTION_WIDTH24); 128 u32 fraction = bits24 & FRACTION_MASK24; 129 130 u32 bits32 = 0; 131 bits32 |= (sign != 0) ? SIGN32 : 0; 132 133 if ((bits24 & ~SIGN24) == 0) 134 { 135 exp = 0; 136 } 137 else 138 { 139 exp = exp - EXP_BIAS24 + EXP_BIAS32; 140 } 141 142 fraction = fraction << (FRACTION_WIDTH32 - FRACTION_WIDTH24); 143 144 // ビット拡張なので、exp がオーバーフローすることは無い。 145 bits32 |= fraction & FRACTION_MASK32; 146 bits32 |= ((u32)exp & 0xFF) << FRACTION_WIDTH32; 147 148 return *reinterpret_cast<f32*>(&bits32); 149 } 150 151 //-------------------------------------------------------------------------- 152 //! @brief f32 から 24bit float に変換します。 153 //! 154 //! @param[in] value 32bit float の値です。 155 //! 156 //! @return 24bit 浮動小数のビット表現を返します。 157 //-------------------------------------------------------------------------- Float32ToBits24(f32 value)158 static u32 Float32ToBits24(f32 value) 159 { 160 u32 bits32 = *reinterpret_cast<u32*>(&value); 161 162 u32 sign = bits32 & SIGN32; 163 int exp = (int)((bits32 & EXP_MASK32) >> FRACTION_WIDTH32); 164 u32 fraction = bits32 & FRACTION_MASK32; 165 166 u32 bits24 = 0; 167 bits24 |= (sign != 0) ? SIGN24 : 0; 168 169 if ((bits32 & ~SIGN32) == 0) 170 { 171 exp = 0; 172 } 173 else 174 { 175 exp = exp - EXP_BIAS32 + EXP_BIAS24; 176 } 177 178 fraction = fraction >> (FRACTION_WIDTH32 - FRACTION_WIDTH24); 179 180 if (exp < 0) 181 { 182 // +0 もしくは -0 なのでそのまま。 183 } 184 else if (exp > 127) 185 { 186 // 無限大の処理 187 // TODO: IEEE float の無限大の表現がGPU上で有効なのかどうかを要確認。 188 bits24 = (u32)0x7F << FRACTION_WIDTH24; 189 } 190 else 191 { 192 bits24 |= fraction & FRACTION_MASK24; 193 bits24 |= ((u32)exp & 0x7F) << FRACTION_WIDTH24; 194 } 195 196 return bits24; 197 } 198 199 private: 200 f32 m_Float32; 201 202 enum 203 { 204 SIGN32 = 0x80000000, 205 SIGN24 = 0x00800000, 206 207 EXP_BIAS32 = 127, 208 EXP_BIAS24 = 63, 209 EXP_MASK32 = 0x7F800000, 210 EXP_MASK24 = 0x007F0000, 211 212 FRACTION_WIDTH32 = 23, 213 FRACTION_MASK32 = 0x007FFFFF, 214 FRACTION_WIDTH24 = 16, 215 FRACTION_MASK24 = 0x0000FFFF 216 }; 217 }; 218 219 //-------------------------------------------------------------------------- 220 //! @brief 31bit 浮動小数用のユーティリティです。 221 // 222 // 31bit 浮動小数のビットフォーマットは次の通りです。 223 // | sign | exponent | fraction | 224 // sign : 符号 1 bit. 225 // exponent : 指数部 7 bit. bias 63. 226 // fraction : 仮数部 23 bit. 227 //--------------------------------------------------------------------------- 228 class Float31 229 { 230 public: 231 //-------------------------------------------------------------------------- 232 //! @brief デフォルトコンストラクタです。 233 //-------------------------------------------------------------------------- Float31()234 Float31() : m_Float32( 0.0f ) {} 235 236 //-------------------------------------------------------------------------- 237 //! @brief コンストラクタです。 238 //! 239 //! @param[in] bits31 31bit 浮動小数のビットを表現した整数値です。 240 //-------------------------------------------------------------------------- Float31(u32 bits31)241 /* implicit */ Float31( u32 bits31 ) 242 { 243 m_Float32 = Bits31ToFloat32( bits31 ); 244 } 245 246 //-------------------------------------------------------------------------- 247 //! @brief コンストラクタです。 248 //! 249 //! @param[in] value 32bit 浮動小数の値から 31bit float を生成します。 250 //-------------------------------------------------------------------------- Float31(f32 value)251 /* implicit */ Float31( f32 value ) : m_Float32( value ) {} 252 GetFloat32Value()253 f32 GetFloat32Value() const { return m_Float32; } GetFloat31Value()254 u32 GetFloat31Value() const { return Float32ToBits31( m_Float32 ); } 255 256 Float31& operator =(f32 value) { this->m_Float32 = value; return *this; } 257 Float31& operator =(u32 bits31) { this->m_Float32 = Bits31ToFloat32( bits31 ); return *this; } 258 f32()259 operator f32() const { return m_Float32; } 260 261 f32 operator +(f32 right) const { return this->m_Float32 + right; } 262 f32 operator -(f32 right) const { return this->m_Float32 - right; } 263 f32 operator *(f32 right) const { return this->m_Float32 * right; } 264 f32 operator /(f32 right) const { return this->m_Float32 / right; } 265 266 Float31& operator +=(f32 rhs) { this->m_Float32 += rhs; return *this; } 267 Float31& operator -=(f32 rhs) { this->m_Float32 -= rhs; return *this; } 268 Float31& operator *=(f32 rhs) { this->m_Float32 *= rhs; return *this; } 269 Float31& operator /=(f32 rhs) { this->m_Float32 /= rhs; return *this; } 270 271 bool operator ==(f32 rhs) const { return (rhs == this->m_Float32); } 272 bool operator !=(f32 rhs) const { return !(*this == rhs); } 273 274 //-------------------------------------------------------------------------- 275 //! @brief 31bit float から 32bit float に変換します。 276 //! 277 //! @param[in] bits31 31bit 浮動小数のビットを表現した整数値です。 278 //! 279 //! @return f32 に変換した値を返します。 280 //-------------------------------------------------------------------------- Bits31ToFloat32(u32 bits31)281 static f32 Bits31ToFloat32(u32 bits31) 282 { 283 u32 sign = bits31 & SIGN31; 284 int exp = (int)((bits31 & EXP_MASK31) >> FRACTION_WIDTH31); 285 u32 fraction = bits31 & FRACTION_MASK31; 286 287 u32 bits32 = 0; 288 bits32 |= (sign != 0) ? SIGN32 : 0; 289 290 if ((bits31 & ~SIGN31) == 0) 291 { 292 exp = 0; 293 } 294 else 295 { 296 exp = exp - EXP_BIAS31 + EXP_BIAS32; 297 } 298 299 // ビット拡張なので、exp がオーバーフローすることは無い。 300 bits32 |= fraction & FRACTION_MASK32; 301 bits32 |= ((u32)exp & 0xFF) << FRACTION_WIDTH32; 302 303 return *reinterpret_cast<f32*>(&bits32); 304 } 305 306 //-------------------------------------------------------------------------- 307 //! @brief f32 から 31bit float に変換します。 308 //! 309 //! @param[in] value 32bit float の値です。 310 //! 311 //! @return 31bit 浮動小数のビット表現を返します。 312 //-------------------------------------------------------------------------- Float32ToBits31(f32 value)313 static u32 Float32ToBits31(f32 value) 314 { 315 u32 bits32 = *reinterpret_cast<u32*>(&value); 316 317 u32 sign = bits32 & SIGN32; 318 int exp = (int)((bits32 & EXP_MASK32) >> FRACTION_WIDTH32); 319 u32 fraction = bits32 & FRACTION_MASK32; 320 321 u32 bits31 = 0; 322 bits31 |= (sign != 0) ? SIGN31 : 0; 323 324 if ((bits32 & ~SIGN32) == 0) 325 { 326 exp = 0; 327 } 328 else 329 { 330 exp = exp - EXP_BIAS32 + EXP_BIAS31; 331 } 332 333 if (exp < 0) 334 { 335 // +0 もしくは -0 なのでそのまま。 336 } 337 else if (exp > 127) 338 { 339 // 無限大の処理 340 // TODO: IEEE float の無限大の表現がGPU上で有効なのかどうかを要確認。 341 bits31 = (u32)0x7F << FRACTION_WIDTH31; 342 } 343 else 344 { 345 bits31 |= fraction & FRACTION_MASK31; 346 bits31 |= ((u32)exp & 0x7F) << FRACTION_WIDTH31; 347 } 348 349 return bits31; 350 } 351 352 private: 353 f32 m_Float32; 354 355 enum 356 { 357 SIGN32 = 0x80000000, 358 SIGN31 = 0x40000000, 359 360 EXP_BIAS32 = 127, 361 EXP_BIAS31 = 63, 362 EXP_MASK32 = 0x7F800000, 363 EXP_MASK31 = 0x3F800000, 364 365 FRACTION_WIDTH32 = 23, 366 FRACTION_MASK32 = 0x007FFFFF, 367 FRACTION_WIDTH31 = 23, 368 FRACTION_MASK31 = 0x007FFFFF 369 }; 370 }; 371 372 373 //-------------------------------------------------------------------------- 374 //! @brief 20bit 浮動小数用のユーティリティです。 375 // 376 // 20bit 浮動小数のビットフォーマットは次の通りです。 377 // | sign | exponent | fraction | 378 // sign : 符号 1 bit. 379 // exponent : 指数部 7 bit. bias 63. 380 // fraction : 仮数部 12 bit. 381 //--------------------------------------------------------------------------- 382 class Float20 383 { 384 public: 385 //-------------------------------------------------------------------------- 386 //! @brief デフォルトコンストラクタです。 387 //-------------------------------------------------------------------------- Float20()388 Float20() : m_Float32( 0.0f ) {} 389 390 //-------------------------------------------------------------------------- 391 //! @brief コンストラクタです。 392 //! 393 //! @param[in] bits20 20bit 浮動小数のビットを表現した整数値です。 394 //-------------------------------------------------------------------------- Float20(u32 bits20)395 /* implicit */ Float20( u32 bits20 ) 396 { 397 m_Float32 = Bits20ToFloat32( bits20 ); 398 } 399 400 //-------------------------------------------------------------------------- 401 //! @brief コンストラクタです。 402 //! 403 //! @param[in] value 32bit 浮動小数の値から 20bit float を生成します。 404 //-------------------------------------------------------------------------- Float20(f32 value)405 /* implicit */ Float20( f32 value ) : m_Float32( value ) {} 406 GetFloat32Value()407 f32 GetFloat32Value() const { return m_Float32; } GetFloat20Value()408 u32 GetFloat20Value() const { return Float32ToBits20( m_Float32 ); } 409 410 Float20& operator =(f32 value) { this->m_Float32 = value; return *this; } 411 Float20& operator =(u32 bits20) { this->m_Float32 = Bits20ToFloat32( bits20 ); return *this; } 412 f32()413 operator f32() const { return m_Float32; } 414 415 f32 operator +(f32 right) const { return this->m_Float32 + right; } 416 f32 operator -(f32 right) const { return this->m_Float32 - right; } 417 f32 operator *(f32 right) const { return this->m_Float32 * right; } 418 f32 operator /(f32 right) const { return this->m_Float32 / right; } 419 420 Float20& operator +=(f32 rhs) { this->m_Float32 += rhs; return *this; } 421 Float20& operator -=(f32 rhs) { this->m_Float32 -= rhs; return *this; } 422 Float20& operator *=(f32 rhs) { this->m_Float32 *= rhs; return *this; } 423 Float20& operator /=(f32 rhs) { this->m_Float32 /= rhs; return *this; } 424 425 bool operator ==(f32 rhs) const { return (rhs == this->m_Float32); } 426 bool operator !=(f32 rhs) const { return !(*this == rhs); } 427 428 //-------------------------------------------------------------------------- 429 //! @brief 20bit float から 32bit float に変換します。 430 //! 431 //! @param[in] bits20 20bit 浮動小数のビットを表現した整数値です。 432 //! 433 //! @return f32 に変換した値を返します。 434 //-------------------------------------------------------------------------- Bits20ToFloat32(u32 bits20)435 static f32 Bits20ToFloat32(u32 bits20) 436 { 437 u32 sign = bits20 & SIGN20; 438 int exp = (int)((bits20 & EXP_MASK20) >> FRACTION_WIDTH20); 439 u32 fraction = bits20 & FRACTION_MASK20; 440 441 u32 bits32 = 0; 442 bits32 |= (sign != 0) ? SIGN32 : 0; 443 444 if ((bits20 & ~SIGN20) == 0) 445 { 446 exp = 0; 447 } 448 else 449 { 450 exp = exp - EXP_BIAS20 + EXP_BIAS32; 451 } 452 453 fraction = fraction << (FRACTION_WIDTH32 - FRACTION_WIDTH20); 454 455 // ビット拡張なので、exp がオーバーフローすることは無い。 456 bits32 |= fraction & FRACTION_MASK32; 457 bits32 |= ((u32)exp & 0xFF) << FRACTION_WIDTH32; 458 459 return *reinterpret_cast<f32*>(&bits32); 460 } 461 462 //-------------------------------------------------------------------------- 463 //! @brief f32 から 20bit float に変換します。 464 //! 465 //! @param[in] value 32bit float の値です。 466 //! 467 //! @return 20bit 浮動小数のビット表現を返します。 468 //-------------------------------------------------------------------------- Float32ToBits20(f32 value)469 static u32 Float32ToBits20(f32 value) 470 { 471 u32 bits32 = *reinterpret_cast<u32*>(&value); 472 473 u32 sign = bits32 & SIGN32; 474 int exp = (int)((bits32 & EXP_MASK32) >> FRACTION_WIDTH32); 475 u32 fraction = bits32 & FRACTION_MASK32; 476 477 u32 bits20 = 0; 478 bits20 |= (sign != 0) ? SIGN20 : 0; 479 480 if ((bits32 & ~SIGN32) == 0) 481 { 482 exp = 0; 483 } 484 else 485 { 486 exp = exp - EXP_BIAS32 + EXP_BIAS20; 487 } 488 489 fraction = fraction >> (FRACTION_WIDTH32 - FRACTION_WIDTH20); 490 491 if (exp < 0) 492 { 493 // +0 もしくは -0 なのでそのまま。 494 } 495 else if (exp > 127) 496 { 497 // 無限大の処理 498 // TODO: IEEE float の無限大の表現がGPU上で有効なのかどうかを要確認。 499 bits20 = (u32)0x7F << FRACTION_WIDTH20; 500 } 501 else 502 { 503 bits20 |= fraction & FRACTION_MASK20; 504 bits20 |= ((u32)exp & 0x7F) << FRACTION_WIDTH20; 505 } 506 507 return bits20; 508 } 509 510 private: 511 f32 m_Float32; 512 513 enum 514 { 515 SIGN32 = 0x80000000, 516 SIGN20 = 0x00080000, 517 518 EXP_BIAS32 = 127, 519 EXP_BIAS20 = 63, 520 EXP_MASK32 = 0x7F800000, 521 EXP_MASK20 = 0x0007F000, 522 523 FRACTION_WIDTH32 = 23, 524 FRACTION_MASK32 = 0x007FFFFF, 525 FRACTION_WIDTH20 = 12, 526 FRACTION_MASK20 = 0x00000FFF 527 }; 528 }; 529 530 531 //-------------------------------------------------------------------------- 532 //! @brief 16bit 浮動小数用のユーティリティです。 533 // 534 // 16bit 浮動小数のビットフォーマットは次の通りです。 535 // | sign | exponent | fraction | 536 // sign : 符号 1 bit. 537 // exponent : 指数部 5 bit. bias 15. 538 // fraction : 仮数部 10 bit. 539 //--------------------------------------------------------------------------- 540 class Float16 541 { 542 public: 543 //-------------------------------------------------------------------------- 544 //! @brief デフォルトコンストラクタです。 545 //-------------------------------------------------------------------------- Float16()546 Float16() : m_Float32( 0.0f ) {} 547 548 //-------------------------------------------------------------------------- 549 //! @brief コンストラクタです。 550 //! 551 //! @param[in] bits16 16bit 浮動小数のビットを表現した整数値です。 552 //-------------------------------------------------------------------------- Float16(u32 bits16)553 /* implicit */ Float16( u32 bits16 ) 554 { 555 m_Float32 = Bits16ToFloat32( bits16 ); 556 } 557 558 //-------------------------------------------------------------------------- 559 //! @brief コンストラクタです。 560 //! 561 //! @param[in] value 32bit 浮動小数の値から 16bit float を生成します。 562 //-------------------------------------------------------------------------- Float16(f32 value)563 /* implicit */ Float16( f32 value ) : m_Float32( value ) {} 564 GetFloat32Value()565 f32 GetFloat32Value() const { return m_Float32; } GetFloat16Value()566 u16 GetFloat16Value() const { return Float32ToBits16( m_Float32 ); } 567 568 Float16& operator =(f32 value) { this->m_Float32 = value; return *this; } 569 Float16& operator =(u32 bits16) { this->m_Float32 = Bits16ToFloat32( bits16 ); return *this; } 570 f32()571 operator f32() const { return m_Float32; } u16()572 operator u16() const { return GetFloat16Value(); } 573 574 f32 operator +(f32 right) const { return this->m_Float32 + right; } 575 f32 operator -(f32 right) const { return this->m_Float32 - right; } 576 f32 operator *(f32 right) const { return this->m_Float32 * right; } 577 f32 operator /(f32 right) const { return this->m_Float32 / right; } 578 579 Float16& operator +=(f32 rhs) { this->m_Float32 += rhs; return *this; } 580 Float16& operator -=(f32 rhs) { this->m_Float32 -= rhs; return *this; } 581 Float16& operator *=(f32 rhs) { this->m_Float32 *= rhs; return *this; } 582 Float16& operator /=(f32 rhs) { this->m_Float32 /= rhs; return *this; } 583 584 bool operator ==(f32 rhs) const { return (rhs == this->m_Float32); } 585 bool operator !=(f32 rhs) const { return !(*this == rhs); } 586 587 //-------------------------------------------------------------------------- 588 //! @brief 16bit float から 32bit float に変換します。 589 //! 590 //! @param[in] bits16 16bit 浮動小数のビットを表現した整数値です。 591 //! 592 //! @return f32 に変換した値を返します。 593 //-------------------------------------------------------------------------- Bits16ToFloat32(u32 bits16)594 static f32 Bits16ToFloat32(u32 bits16) 595 { 596 u32 sign = bits16 & SIGN16; 597 int exp = (int)((bits16 & EXP_MASK16) >> FRACTION_WIDTH16); 598 u32 fraction = bits16 & FRACTION_MASK16; 599 600 u32 bits32 = 0; 601 bits32 |= (sign != 0) ? SIGN32 : 0; 602 603 if ((bits16 & ~SIGN16) == 0) 604 { 605 exp = 0; 606 } 607 else 608 { 609 exp = exp - EXP_BIAS16 + EXP_BIAS32; 610 } 611 612 fraction = fraction << (FRACTION_WIDTH32 - FRACTION_WIDTH16); 613 614 // ビット拡張なので、exp がオーバーフローすることは無い。 615 bits32 |= fraction & FRACTION_MASK32; 616 bits32 |= ((u32)exp & 0xFF) << FRACTION_WIDTH32; 617 618 return *reinterpret_cast<f32*>(&bits32); 619 } 620 621 //-------------------------------------------------------------------------- 622 //! @brief f32 から 16bit float に変換します。 623 //! 624 //! @param[in] value 32bit float の値です。 625 //! 626 //! @return 16bit 浮動小数のビット表現を返します。 627 //-------------------------------------------------------------------------- Float32ToBits16(f32 value)628 static u16 Float32ToBits16(f32 value) 629 { 630 u32 bits32 = *reinterpret_cast<u32*>(&value); 631 632 u32 sign = bits32 & SIGN32; 633 int exp = (int)((bits32 & EXP_MASK32) >> FRACTION_WIDTH32); 634 u32 fraction = bits32 & FRACTION_MASK32; 635 636 u32 bits16 = 0; 637 bits16 |= (sign != 0) ? SIGN16 : 0; 638 639 if ((bits32 & ~SIGN32) == 0) 640 { 641 exp = 0; 642 } 643 else 644 { 645 exp = exp - EXP_BIAS32 + EXP_BIAS16; 646 } 647 648 fraction = fraction >> (FRACTION_WIDTH32 - FRACTION_WIDTH16); 649 650 if (exp < 0) 651 { 652 // +0 もしくは -0 なのでそのまま。 653 } 654 else if (exp > 31) 655 { 656 // 無限大の処理 657 // TODO: IEEE float の無限大の表現がGPU上で有効なのかどうかを要確認。 658 bits16 = (u32)0x1F << FRACTION_WIDTH16; 659 } 660 else 661 { 662 bits16 |= fraction & FRACTION_MASK16; 663 bits16 |= ((u32)exp & 0x1F) << FRACTION_WIDTH16; 664 } 665 666 return static_cast<u16>(bits16); 667 } 668 669 private: 670 f32 m_Float32; 671 672 enum 673 { 674 SIGN32 = 0x80000000, 675 SIGN16 = 0x00008000, 676 677 EXP_BIAS32 = 127, 678 EXP_BIAS16 = 15, 679 EXP_MASK32 = 0x7F800000, 680 EXP_MASK16 = 0x00007C00, 681 682 FRACTION_WIDTH32 = 23, 683 FRACTION_MASK32 = 0x007FFFFF, 684 FRACTION_WIDTH16 = 10, 685 FRACTION_MASK16 = 0x000003FF 686 }; 687 }; 688 689 //-------------------------------------------------------------------------- 690 //! @brief 13bit 固定小数用のユーティリティです。 691 // 692 // 13bit 固定小数のビットフォーマットは次の通りです。 693 // | int | decimal | (2の補数) 694 // int : 整数部 2 bit. 695 // decimal : 小数部 11 bit. 696 //--------------------------------------------------------------------------- 697 class Fixed13 698 { 699 public: 700 //-------------------------------------------------------------------------- 701 //! @brief デフォルトコンストラクタです。 702 //-------------------------------------------------------------------------- Fixed13()703 Fixed13() : m_Float32( 0.0f ) {} 704 705 //-------------------------------------------------------------------------- 706 //! @brief コンストラクタです。 707 //! 708 //! @param[in] fixed13 13bit 固定小数のビットを表現した整数値です。 709 //-------------------------------------------------------------------------- Fixed13(u32 fixed13)710 explicit Fixed13( u32 fixed13 ) 711 { 712 m_Float32 = Fixed13ToFloat32( fixed13 ); 713 } 714 715 //-------------------------------------------------------------------------- 716 //! @brief コンストラクタです。 717 //! 718 //! @param[in] fvalue 32bit 浮動小数の値です。 719 //-------------------------------------------------------------------------- Fixed13(f32 fvalue)720 explicit Fixed13( f32 fvalue ) 721 { 722 m_Float32 = fvalue; 723 } 724 725 GetFloat32Value()726 f32 GetFloat32Value() const { return m_Float32; } GetFixed13Value()727 u16 GetFixed13Value() const { return Float32ToFixed13( m_Float32 ); } 728 729 //-------------------------------------------------------------------------- 730 //! @brief 13bit fixed から 32bit float に変換します。 731 //! 732 //! @param[in] fixed13 13bit 固定小数のビットを表現した整数値です。 733 //! 734 //! @return f32 に変換した値を返します。 735 //-------------------------------------------------------------------------- Fixed13ToFloat32(u32 fixed13)736 static f32 Fixed13ToFloat32(u32 fixed13) 737 { 738 f32 float32 = static_cast<f32>(fixed13); 739 740 if (fixed13 & (0x1 << (TOTAL_WIDTH - 1))) 741 { 742 float32 -= (0x1 << TOTAL_WIDTH); 743 } 744 745 return float32 / (0x1 << DECIMAL_WIDTH); 746 } 747 748 //-------------------------------------------------------------------------- 749 //! @brief f32 から 13bit fixed に変換します。 750 //! 751 //! @param[in] value 32bit float の値です。 752 //! 753 //! @return 16bit 浮動小数のビット表現を返します。 754 //-------------------------------------------------------------------------- Float32ToFixed13(f32 value)755 static u16 Float32ToFixed13(f32 value) 756 { 757 f32 fixed = value; 758 fixed += ((0x1 << INT_WIDTH) / 2); 759 fixed *= (0x1 << DECIMAL_WIDTH); 760 761 if (fixed < 0) 762 { 763 fixed = 0.0f; 764 } 765 else if (fixed >= (0x1 << TOTAL_WIDTH)) 766 { 767 fixed = (0x1 << TOTAL_WIDTH) - 1; 768 } 769 770 fixed -= 0x1 << (TOTAL_WIDTH - 1); 771 772 return static_cast<u16>(static_cast<s16>(fixed) & MASK); 773 } 774 775 private: 776 f32 m_Float32; 777 778 enum 779 { 780 INT_WIDTH = 2, 781 DECIMAL_WIDTH = 11, 782 TOTAL_WIDTH = 13, 783 MASK = (0x1 << TOTAL_WIDTH) - 1 784 }; 785 }; 786 787 //-------------------------------------------------------------------------- 788 //! @brief 13bit 固定小数用のユーティリティです。 789 // 790 // 13bit 固定小数のビットフォーマットは次の通りです。 791 // | sign | int | decimal | (2の補数) 792 // int : 整数部 5 bit. 793 // decimal : 小数部 8 bit. 794 //--------------------------------------------------------------------------- 795 class FixedS13Fraction8 796 { 797 public: 798 //-------------------------------------------------------------------------- 799 //! @brief デフォルトコンストラクタです。 800 //-------------------------------------------------------------------------- FixedS13Fraction8()801 FixedS13Fraction8() : m_Float32( 0.0f ) {} 802 803 //-------------------------------------------------------------------------- 804 //! @brief コンストラクタです。 805 //! 806 //! @param[in] fixed13 13bit 固定小数のビットを表現した整数値です。 807 //-------------------------------------------------------------------------- FixedS13Fraction8(u32 fixed13)808 explicit FixedS13Fraction8( u32 fixed13 ) 809 { 810 m_Float32 = Fixed13ToFloat32( fixed13 ); 811 } 812 813 //-------------------------------------------------------------------------- 814 //! @brief コンストラクタです。 815 //! 816 //! @param[in] fvalue 32bit 浮動小数の値です。 817 //-------------------------------------------------------------------------- FixedS13Fraction8(f32 fvalue)818 explicit FixedS13Fraction8( f32 fvalue ) 819 { 820 m_Float32 = fvalue; 821 } 822 823 GetFloat32Value()824 f32 GetFloat32Value() const { return m_Float32; } GetFixed13Value()825 u16 GetFixed13Value() const { return Float32ToFixed13( m_Float32 ); } 826 827 //-------------------------------------------------------------------------- 828 //! @brief 13bit fixed から 32bit float に変換します。 829 //! 830 //! @param[in] fixed13 13bit 固定小数のビットを表現した整数値です。 831 //! 832 //! @return f32 に変換した値を返します。 833 //-------------------------------------------------------------------------- Fixed13ToFloat32(u32 fixed13)834 static f32 Fixed13ToFloat32(u32 fixed13) 835 { 836 f32 float32 = static_cast<f32>(fixed13); 837 838 if (fixed13 & (0x1 << (TOTAL_WIDTH - 1))) 839 { 840 float32 -= (0x1 << TOTAL_WIDTH); 841 } 842 843 return float32 / (0x1 << DECIMAL_WIDTH); 844 } 845 846 //-------------------------------------------------------------------------- 847 //! @brief f32 から 13bit fixed に変換します。 848 //! 849 //! @param[in] value 32bit float の値です。 850 //! 851 //! @return 13bit 固定小数のビット表現を返します。 852 //-------------------------------------------------------------------------- Float32ToFixed13(f32 value)853 static u16 Float32ToFixed13(f32 value) 854 { 855 f32 fixed = value; 856 fixed += ((0x1 << INT_WIDTH) / 2); 857 fixed *= (0x1 << DECIMAL_WIDTH); 858 859 if (fixed < 0) 860 { 861 fixed = 0.0f; 862 } 863 else if (fixed >= (0x1 << TOTAL_WIDTH)) 864 { 865 fixed = (0x1 << TOTAL_WIDTH) - 1; 866 } 867 868 fixed -= 0x1 << (TOTAL_WIDTH - 1); 869 870 return static_cast<u16>(static_cast<s16>(fixed) & MASK); 871 } 872 873 private: 874 f32 m_Float32; 875 876 enum 877 { 878 INT_WIDTH = 5, 879 DECIMAL_WIDTH = 8, 880 TOTAL_WIDTH = 13, 881 MASK = (0x1 << TOTAL_WIDTH) - 1 882 }; 883 }; 884 885 //-------------------------------------------------------------------------- 886 //! @brief 11bit 固定小数用のユーティリティです。 887 // 888 // 11bit 固定小数のビットフォーマットは次の通りです。 889 // decimal : 小数部 11 bit. 890 //--------------------------------------------------------------------------- 891 class Fixed11 892 { 893 public: 894 //-------------------------------------------------------------------------- 895 //! @brief デフォルトコンストラクタです。 896 //-------------------------------------------------------------------------- Fixed11()897 Fixed11() : m_Float32( 0.0f ) {} 898 899 //-------------------------------------------------------------------------- 900 //! @brief コンストラクタです。 901 //! 902 //! @param[in] fixed11 11bit 固定小数のビットを表現した整数値です。 903 //-------------------------------------------------------------------------- Fixed11(u32 fixed11)904 explicit Fixed11( u32 fixed11 ) 905 { 906 m_Float32 = Fixed11ToFloat32( fixed11 ); 907 } 908 909 //-------------------------------------------------------------------------- 910 //! @brief コンストラクタです。 911 //! 912 //! @param[in] fvalue 32bit 浮動小数の値です。 913 //-------------------------------------------------------------------------- Fixed11(f32 fvalue)914 explicit Fixed11( f32 fvalue ) 915 { 916 m_Float32 = fvalue; 917 } 918 919 GetFloat32Value()920 f32 GetFloat32Value() const { return m_Float32; } GetFixed11Value()921 u16 GetFixed11Value() const { return Float32ToFixed11( m_Float32 ); } 922 923 //-------------------------------------------------------------------------- 924 //! @brief 11bit fixed から 32bit float に変換します。 925 //! 926 //! @param[in] fixed11 11bit 固定小数のビットを表現した整数値です。 927 //! 928 //! @return f32 に変換した値を返します。 929 //-------------------------------------------------------------------------- Fixed11ToFloat32(u32 fixed11)930 static f32 Fixed11ToFloat32(u32 fixed11) 931 { 932 f32 float32 = static_cast<f32>(fixed11); 933 return float32 / MASK; 934 } 935 936 //-------------------------------------------------------------------------- 937 //! @brief f32 から 11bit fixed に変換します。 938 //! 939 //! @param[in] value 32bit float の値です。 940 //! 941 //! @return 11bit 固定小数のビット表現を返します。 942 //-------------------------------------------------------------------------- Float32ToFixed11(f32 value)943 static u16 Float32ToFixed11(f32 value) 944 { 945 u32 fixed; 946 u32 v_ = *(u32*)&value; 947 948 if (value <= 0 || (v_ & 0x7f800000) == 0x7f800000) 949 { 950 fixed = 0; 951 } 952 else 953 { 954 value *= 1 << (DECIMAL_WIDTH - 0); 955 if (value >= (1 << DECIMAL_WIDTH)) 956 { 957 fixed = (1 << DECIMAL_WIDTH) - 1; 958 } 959 else 960 { 961 fixed = (unsigned)(value); 962 } 963 } 964 965 return static_cast<u16>(static_cast<s16>(fixed) & MASK); 966 } 967 968 private: 969 f32 m_Float32; 970 971 enum 972 { 973 INT_WIDTH = 2, 974 DECIMAL_WIDTH = 11, 975 TOTAL_WIDTH = 11, 976 MASK = (0x1 << TOTAL_WIDTH) - 1 977 }; 978 }; 979 980 //-------------------------------------------------------------------------- 981 //! @brief 24bit 固定小数用のユーティリティです。 982 // 983 // 24bit 固定小数のビットフォーマットは次の通りです。 984 // decimal : 小数部 24 bit. 985 //--------------------------------------------------------------------------- 986 class FixedU24 987 { 988 public: 989 //-------------------------------------------------------------------------- 990 //! @brief デフォルトコンストラクタです。 991 //-------------------------------------------------------------------------- FixedU24()992 FixedU24() : m_Float32( 0.0f ) {} 993 994 //-------------------------------------------------------------------------- 995 //! @brief コンストラクタです。 996 //! 997 //! @param[in] fixedU24 24bit 固定小数のビットを表現した整数値です。 998 //-------------------------------------------------------------------------- FixedU24(u32 fixedU24)999 explicit FixedU24( u32 fixedU24 ) 1000 { 1001 m_Float32 = FixedU24ToFloat32( fixedU24 ); 1002 } 1003 1004 //-------------------------------------------------------------------------- 1005 //! @brief コンストラクタです。 1006 //! 1007 //! @param[in] fvalue 32bit 浮動小数の値です。 1008 //-------------------------------------------------------------------------- FixedU24(f32 fvalue)1009 explicit FixedU24( f32 fvalue ) 1010 { 1011 m_Float32 = fvalue; 1012 } 1013 1014 GetFloat32Value()1015 f32 GetFloat32Value() const { return m_Float32; } GetFixedU24Value()1016 u32 GetFixedU24Value() const { return Float32ToFixedU24( m_Float32 ); } 1017 1018 //-------------------------------------------------------------------------- 1019 //! @brief 24bit fixed から 32bit float に変換します。 1020 //! 1021 //! @param[in] fixedU24 24bit 固定小数のビットを表現した整数値です。 1022 //! 1023 //! @return f32 に変換した値を返します。 1024 //-------------------------------------------------------------------------- FixedU24ToFloat32(u32 fixedU24)1025 static f32 FixedU24ToFloat32(u32 fixedU24) 1026 { 1027 f32 float32 = static_cast<f32>(fixedU24); 1028 return float32 / MASK; 1029 } 1030 1031 //-------------------------------------------------------------------------- 1032 //! @brief f32 から 24bit fixed に変換します。 1033 //! 1034 //! @param[in] value 32bit float の値です。 1035 //! 1036 //! @return 24bit 固定小数小数のビット表現を返します。 1037 //-------------------------------------------------------------------------- Float32ToFixedU24(f32 value)1038 static u32 Float32ToFixedU24(f32 value) 1039 { 1040 u32 fixed; 1041 u32 v_ = *(u32*)&value; 1042 1043 if (value <= 0 || (v_ & 0x7f800000) == 0x7f800000) 1044 { 1045 fixed = 0; 1046 } 1047 else 1048 { 1049 value *= 1 << (DECIMAL_WIDTH - 0); 1050 if (value >= (1 << DECIMAL_WIDTH)) 1051 { 1052 fixed = (1 << DECIMAL_WIDTH) - 1; 1053 } 1054 else 1055 { 1056 fixed = (unsigned)(value); 1057 } 1058 } 1059 1060 return static_cast<u32>(static_cast<s32>(fixed) & MASK); 1061 } 1062 1063 private: 1064 f32 m_Float32; 1065 1066 enum 1067 { 1068 INT_WIDTH = 2, 1069 DECIMAL_WIDTH = 24, 1070 TOTAL_WIDTH = 24, 1071 MASK = (0x1 << TOTAL_WIDTH) - 1 1072 }; 1073 }; 1074 1075 } /* namespace ut */ 1076 } /* namespace nw */ 1077 1078 #endif // NW_UT_FLOAT24_H_ 1079