1 | */* scalbnq.c -- __float128 version of s_scalbn.c.* |

2 | * * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.* |

3 | * */* |

4 | |

5 | */** |

6 | * * ====================================================* |

7 | * * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.* |

8 | * ** |

9 | * * Developed at SunPro, a Sun Microsystems, Inc. business.* |

10 | * * Permission to use, copy, modify, and distribute this* |

11 | * * software is freely granted, provided that this notice* |

12 | * * is preserved.* |

13 | * * ====================================================* |

14 | * */* |

15 | |

16 | |

17 | */** |

18 | * * scalbnq (__float128 x, int n)* |

19 | * * scalbnq(x,n) returns x* 2**n computed by exponent* |

20 | * * manipulation rather than by actually performing an* |

21 | * * exponentiation or a multiplication.* |

22 | * */* |

23 | |

24 | __#include "quadmath-imp.h"__ |

25 | |

26 | *static* *const* **__float128** |

27 | two114 = `2.0769187434139310514121985316880384E+34Q`, */* 0x4071000000000000, 0 */* |

28 | twom114 = `4.8148248609680896326399448564623183E-35Q`, */* 0x3F8D000000000000, 0 */* |

29 | huge = `1.0E+4900Q`, |

30 | tiny = `1.0E-4900Q`; |

31 | |

32 | **__float128** |

33 | scalbnq (**__float128** x, *int* n) |

34 | { |

35 | int64_t k,hx,lx; |

36 | GET_FLT128_WORDS64(hx,lx,x); |

37 | k = (hx>>`48`)&`0x7fff`; */* extract exponent */* |

38 | **if** (k==`0`) { */* 0 or subnormal x */* |

39 | **if** ((lx|(hx&`0x7fffffffffffffffULL`))==`0`) **return** x; */* +-0 */* |

40 | x *= two114; |

41 | GET_FLT128_MSW64(hx,x); |

42 | k = ((hx>>`48`)&`0x7fff`) - `114`; |

43 | } |

44 | **if** (k==`0x7fff`) **return** x+x; */* NaN or Inf */* |

45 | **if** (n< -`50000`) **return** tiny*copysignq(tiny,x); */*underflow*/* |

46 | **if** (n> `50000` || k+n > `0x7ffe`) |

47 | **return** huge*copysignq(huge,x); */* overflow */* |

48 | */* Now k and n are bounded we know that k = k+n does not* |

49 | * overflow. */* |

50 | k = k+n; |

51 | **if** (k > `0`) */* normal result */* |

52 | {SET_FLT128_MSW64(x,(hx&`0x8000ffffffffffffULL`)|(k<<`48`)); **return** x;} |

53 | **if** (k <= -`114`) |

54 | **return** tiny*copysignq(tiny,x); */*underflow*/* |

55 | k += `114`; */* subnormal result */* |

56 | SET_FLT128_MSW64(x,(hx&`0x8000ffffffffffffULL`)|(k<<`48`)); |

57 | **return** x*twom114; |

58 | } |

59 | |