Class for 1.31 unsigned floating-point computation
| 1836 | |
| 1837 | /// Class for 1.31 unsigned floating-point computation |
| 1838 | struct f31 |
| 1839 | { |
| 1840 | /// Constructor. |
| 1841 | /// \param mant mantissa as 1.31 |
| 1842 | /// \param e exponent |
| 1843 | HALF_CONSTEXPR f31(uint32 mant, int e) : m(mant), exp(e) {} |
| 1844 | |
| 1845 | /// Constructor. |
| 1846 | /// \param abs unsigned half-precision value |
| 1847 | f31(unsigned int abs) : exp(-15) |
| 1848 | { |
| 1849 | for(; abs<0x400; abs<<=1,--exp) ; |
| 1850 | m = static_cast<uint32>((abs&0x3FF)|0x400) << 21; |
| 1851 | exp += (abs>>10); |
| 1852 | } |
| 1853 | |
| 1854 | /// Addition operator. |
| 1855 | /// \param a first operand |
| 1856 | /// \param b second operand |
| 1857 | /// \return \a a + \a b |
| 1858 | friend f31 operator+(f31 a, f31 b) |
| 1859 | { |
| 1860 | if(b.exp > a.exp) |
| 1861 | std::swap(a, b); |
| 1862 | int d = a.exp - b.exp; |
| 1863 | uint32 m = a.m + ((d<32) ? (b.m>>d) : 0); |
| 1864 | int i = (m&0xFFFFFFFF) < a.m; |
| 1865 | return f31(((m+i)>>i)|0x80000000, a.exp+i); |
| 1866 | } |
| 1867 | |
| 1868 | /// Subtraction operator. |
| 1869 | /// \param a first operand |
| 1870 | /// \param b second operand |
| 1871 | /// \return \a a - \a b |
| 1872 | friend f31 operator-(f31 a, f31 b) |
| 1873 | { |
| 1874 | int d = a.exp - b.exp, exp = a.exp; |
| 1875 | uint32 m = a.m - ((d<32) ? (b.m>>d) : 0); |
| 1876 | if(!m) |
| 1877 | return f31(0, -32); |
| 1878 | for(; m<0x80000000; m<<=1,--exp) ; |
| 1879 | return f31(m, exp); |
| 1880 | } |
| 1881 | |
| 1882 | /// Multiplication operator. |
| 1883 | /// \param a first operand |
| 1884 | /// \param b second operand |
| 1885 | /// \return \a a * \a b |
| 1886 | friend f31 operator*(f31 a, f31 b) |
| 1887 | { |
| 1888 | uint32 m = multiply64(a.m, b.m); |
| 1889 | int i = m >> 31; |
| 1890 | return f31(m<<(1-i), a.exp + b.exp + i); |
| 1891 | } |
| 1892 | |
| 1893 | /// Division operator. |
| 1894 | /// \param a first operand |
| 1895 | /// \param b second operand |