ceilf.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*++
  2. Copyright (c) 2017 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. ceilf.c
  9. Abstract:
  10. This module implements support for the ceiling math functions.
  11. Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  12. Developed at SunPro, a Sun Microsystems, Inc. business.
  13. Permission to use, copy, modify, and distribute this
  14. software is freely granted, provided that this notice
  15. is preserved.
  16. Author:
  17. Chris Stevens 4-Jan-2017
  18. Environment:
  19. User Mode C Library
  20. --*/
  21. //
  22. // ------------------------------------------------------------------- Includes
  23. //
  24. #include "../libcp.h"
  25. #include "mathp.h"
  26. //
  27. // ---------------------------------------------------------------- Definitions
  28. //
  29. //
  30. // ------------------------------------------------------ Data Type Definitions
  31. //
  32. //
  33. // ----------------------------------------------- Internal Function Prototypes
  34. //
  35. //
  36. // -------------------------------------------------------------------- Globals
  37. //
  38. //
  39. // ------------------------------------------------------------------ Functions
  40. //
  41. LIBC_API
  42. float
  43. ceilf (
  44. float Value
  45. )
  46. /*++
  47. Routine Description:
  48. This routine computes the smallest integral value not less then the given
  49. value.
  50. Arguments:
  51. Value - Supplies the value to compute the ceiling of.
  52. Return Value:
  53. Returns the ceiling on success.
  54. NaN if the given value is NaN.
  55. Returns the value itself for +/- 0 and +/- Infinity.
  56. --*/
  57. {
  58. LONG Exponent;
  59. ULONG NonExponent;
  60. FLOAT_PARTS Parts;
  61. LONG Word;
  62. Parts.Float= Value;
  63. Word = Parts.Ulong;
  64. Exponent = ((Word & FLOAT_EXPONENT_MASK) >> FLOAT_EXPONENT_SHIFT) -
  65. FLOAT_EXPONENT_BIAS;
  66. if (Exponent < 23) {
  67. //
  68. // Raise an inexact if the value isn't zero.
  69. //
  70. if (Exponent < 0) {
  71. //
  72. // Return 0 * sign(Value) if |Value| < 1.
  73. //
  74. if (ClFloatHugeValue + Value > (float)0.0) {
  75. if (Word < 0) {
  76. Word = FLOAT_SIGN_BIT;
  77. } else if (Word != 0) {
  78. Word = FLOAT_ONE_WORD;
  79. }
  80. }
  81. } else {
  82. NonExponent = FLOAT_VALUE_MASK >> Exponent;
  83. //
  84. // Return the value itself if it's integral.
  85. //
  86. if ((Word & NonExponent) == 0) {
  87. return Value;
  88. }
  89. //
  90. // Raise the inexact flag.
  91. //
  92. if (ClFloatHugeValue + Value > (float)0.0) {
  93. if (Word > 0) {
  94. Word += (1 << FLOAT_EXPONENT_SHIFT) >> Exponent;
  95. }
  96. Word &= ~NonExponent;
  97. }
  98. }
  99. } else {
  100. //
  101. // Handle infinity or NaN.
  102. //
  103. if (Exponent == (FLOAT_NAN_EXPONENT - FLOAT_EXPONENT_BIAS)) {
  104. return Value + Value;
  105. //
  106. // Return the value itself if it is integral.
  107. //
  108. } else {
  109. return Value;
  110. }
  111. }
  112. Parts.Ulong = Word;
  113. return Parts.Float;
  114. }
  115. //
  116. // --------------------------------------------------------- Internal Functions
  117. //