Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
2.9 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. largediv.c
  5. Abstract:
  6. This module implements the NT runtime library large integer divide
  7. routines.
  8. N.B. These routines use a one bit at a time algorithm and is slow.
  9. They should be used only when absolutely necessary.
  10. Author:
  11. David N. Cutler 10-Aug-1992
  12. Revision History:
  13. --*/
  14. #include "ntrtlp.h"
  15. LARGE_INTEGER
  16. RtlLargeIntegerDivide (
  17. IN LARGE_INTEGER Dividend,
  18. IN LARGE_INTEGER Divisor,
  19. OUT PLARGE_INTEGER Remainder OPTIONAL
  20. )
  21. /*++
  22. Routine Description:
  23. This routine divides an unsigned 64-bit dividend by an unsigned 64-bit
  24. divisor and returns a 64-bit quotient, and optionally a 64-bit remainder.
  25. Arguments:
  26. Dividend - Supplies the 64-bit dividend for the divide operation.
  27. Divisor - Supplies the 64-bit divisor for the divide operation.
  28. Remainder - Supplies an optional pointer to a variable which receives
  29. the remainder
  30. Return Value:
  31. The 64-bit quotient is returned as the function value.
  32. --*/
  33. {
  34. ULONG Index = 64;
  35. LARGE_INTEGER Partial = {0, 0};
  36. LARGE_INTEGER Quotient;
  37. #ifndef BLDR_KERNEL_RUNTIME
  38. //
  39. // Check for divide by zero
  40. //
  41. if (!(Divisor.LowPart | Divisor.HighPart)) {
  42. RtlRaiseStatus (STATUS_INTEGER_DIVIDE_BY_ZERO);
  43. }
  44. #endif
  45. //
  46. // Loop through the dividend bits and compute the quotient and remainder.
  47. //
  48. Quotient = Dividend;
  49. do {
  50. //
  51. // Shift the next dividend bit into the parital remainder and shift
  52. // the partial quotient (dividend) left one bit.
  53. //
  54. Partial.HighPart = (Partial.HighPart << 1) | (Partial.LowPart >> 31);
  55. Partial.LowPart = (Partial.LowPart << 1) | ((ULONG)Quotient.HighPart >> 31);
  56. Quotient.HighPart = (Quotient.HighPart << 1) | (Quotient.LowPart >> 31);
  57. Quotient.LowPart <<= 1;
  58. //
  59. // If the partial remainder is greater than or equal to the divisor,
  60. // then subtract the divisor from the partial remainder and insert a
  61. // one bit into the quotient.
  62. //
  63. if (((ULONG)Partial.HighPart > (ULONG)Divisor.HighPart) ||
  64. ((Partial.HighPart == Divisor.HighPart) &&
  65. (Partial.LowPart >= Divisor.LowPart))) {
  66. Quotient.LowPart |= 1;
  67. Partial.HighPart -= Divisor.HighPart;
  68. if (Partial.LowPart < Divisor.LowPart) {
  69. Partial.HighPart -= 1;
  70. }
  71. Partial.LowPart -= Divisor.LowPart;
  72. }
  73. Index -= 1;
  74. } while (Index > 0);
  75. //
  76. // If the remainder is requested, then return the 64-bit remainder.
  77. //
  78. if (ARGUMENT_PRESENT(Remainder)) {
  79. *Remainder = Partial;
  80. }
  81. //
  82. // Return the 64-bit quotient.
  83. //
  84. return Quotient;
  85. }