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