| 1786 | /// \exception FE_UNDERFLOW on underflows |
| 1787 | /// \exception FE_INEXACT if no other exception occurred |
| 1788 | template<std::float_round_style R,bool S> unsigned int area(unsigned int arg) |
| 1789 | { |
| 1790 | int abs = arg & 0x7FFF, expx = (abs>>10) + (abs<=0x3FF) - 15, expy = -15, ilog, i; |
| 1791 | uint32 mx = static_cast<uint32>((abs&0x3FF)|((abs>0x3FF)<<10)) << 20, my, r; |
| 1792 | for(; abs<0x400; abs<<=1,--expy) ; |
| 1793 | expy += abs >> 10; |
| 1794 | r = ((abs&0x3FF)|0x400) << 5; |
| 1795 | r *= r; |
| 1796 | i = r >> 31; |
| 1797 | expy = 2*expy + i; |
| 1798 | r >>= i; |
| 1799 | if(S) |
| 1800 | { |
| 1801 | if(expy < 0) |
| 1802 | { |
| 1803 | r = 0x40000000 + ((expy>-30) ? ((r>>-expy)|((r&((static_cast<uint32>(1)<<-expy)-1))!=0)) : 1); |
| 1804 | expy = 0; |
| 1805 | } |
| 1806 | else |
| 1807 | { |
| 1808 | r += 0x40000000 >> expy; |
| 1809 | i = r >> 31; |
| 1810 | r = (r>>i) | (r&i); |
| 1811 | expy += i; |
| 1812 | } |
| 1813 | } |
| 1814 | else |
| 1815 | { |
| 1816 | r -= 0x40000000 >> expy; |
| 1817 | for(; r<0x40000000; r<<=1,--expy) ; |
| 1818 | } |
| 1819 | my = sqrt<30>(r, expy); |
| 1820 | my = (my<<15) + (r<<14)/my; |
| 1821 | if(S) |
| 1822 | { |
| 1823 | mx >>= expy - expx; |
| 1824 | ilog = expy; |
| 1825 | } |
| 1826 | else |
| 1827 | { |
| 1828 | my >>= expx - expy; |
| 1829 | ilog = expx; |
| 1830 | } |
| 1831 | my += mx; |
| 1832 | i = my >> 31; |
| 1833 | static const int G = S && (R==std::round_to_nearest); |
| 1834 | return log2_post<R,0xB8AA3B2A>(log2(my>>i, 26+S+G)+(G<<3), ilog+i, 17, arg&(static_cast<unsigned>(S)<<15)); |
| 1835 | } |
| 1836 | |
| 1837 | /// Class for 1.31 unsigned floating-point computation |
| 1838 | struct f31 |