1 | */* modfq.c -- __float128 version of s_modf.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 | __#include "quadmath-imp.h"__ |

17 | |

18 | *static* *const* **__float128** one = `1.0`; |

19 | |

20 | **__float128** |

21 | modfq (**__float128** x, **__float128** *iptr) |

22 | { |

23 | int64_t i0,i1,j0; |

24 | uint64_t i; |

25 | GET_FLT128_WORDS64(i0,i1,x); |

26 | j0 = ((i0>>`48`)&`0x7fff`)-`0x3fff`; */* exponent of x */* |

27 | **if**(j0<`48`) { */* integer part in high x */* |

28 | **if**(j0<`0`) { */* |x|<1 */* |

29 | */* *iptr = +-0 */* |

30 | SET_FLT128_WORDS64(*iptr,i0&`0x8000000000000000ULL`,`0`); |

31 | **return** x; |

32 | } **else** { |

33 | i = (`0x0000ffffffffffffLL`)>>j0; |

34 | **if**(((i0&i)|i1)==`0`) { */* x is integral */* |

35 | *iptr = x; |

36 | */* return +-0 */* |

37 | SET_FLT128_WORDS64(x,i0&`0x8000000000000000ULL`,`0`); |

38 | **return** x; |

39 | } **else** { |

40 | SET_FLT128_WORDS64(*iptr,i0&(~i),`0`); |

41 | **return** x - *iptr; |

42 | } |

43 | } |

44 | } **else** **if** (j0>`111`) { */* no fraction part */* |

45 | *iptr = x*one; |

46 | */* We must handle NaNs separately. */* |

47 | **if** (j0 == `0x4000` && ((i0 & `0x0000ffffffffffffLL`) | i1)) |

48 | **return** x*one; |

49 | */* return +-0 */* |

50 | SET_FLT128_WORDS64(x,i0&`0x8000000000000000ULL`,`0`); |

51 | **return** x; |

52 | } **else** { */* fraction part in low x */* |

53 | i = -`1ULL`>>(j0-`48`); |

54 | **if**((i1&i)==`0`) { */* x is integral */* |

55 | *iptr = x; |

56 | */* return +-0 */* |

57 | SET_FLT128_WORDS64(x,i0&`0x8000000000000000ULL`,`0`); |

58 | **return** x; |

59 | } **else** { |

60 | SET_FLT128_WORDS64(*iptr,i0,i1&(~i)); |

61 | **return** x - *iptr; |

62 | } |

63 | } |

64 | } |

65 | |