math.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Division and Modulo without / and %
  2. word divmod(word dividend, word divisor, word* rem)
  3. {
  4. word quotient = 1;
  5. word neg = 1;
  6. if ((dividend>0 &&divisor<0)||(dividend<0 && divisor>0))
  7. neg = -1;
  8. // Convert to positive
  9. word tempdividend = (dividend < 0) ? -dividend : dividend;
  10. word tempdivisor = (divisor < 0) ? -divisor : divisor;
  11. if (tempdivisor == tempdividend) {
  12. *rem = 0;
  13. return 1*neg;
  14. }
  15. else if (tempdividend < tempdivisor) {
  16. if (dividend < 0)
  17. *rem = tempdividend*neg;
  18. else
  19. *rem = tempdividend;
  20. return 0;
  21. }
  22. while (tempdivisor<<1 <= tempdividend)
  23. {
  24. tempdivisor = tempdivisor << 1;
  25. quotient = quotient << 1;
  26. }
  27. // Call division recursively
  28. if(dividend < 0)
  29. quotient = quotient*neg + divmod(-(tempdividend-tempdivisor), divisor, rem);
  30. else
  31. quotient = quotient*neg + divmod(tempdividend-tempdivisor, divisor, rem);
  32. return quotient;
  33. }
  34. word division(word dividend, word divisor)
  35. {
  36. word rem = 0;
  37. return divmod(dividend, divisor, &rem);
  38. }
  39. word modulo(word dividend, word divisor)
  40. {
  41. word rem = 0;
  42. divmod(dividend, divisor, &rem);
  43. return rem;
  44. }
  45. // Unsigned Division and Modulo without / and %
  46. word MATH_divmodU(word dividend, word divisor, word mod)
  47. {
  48. word quotient = 0;
  49. word remainder = 0;
  50. if(divisor == 0)
  51. return 0;
  52. word i;
  53. for(i = 31 ; i >= 0 ; i--)
  54. {
  55. quotient = quotient << 1;
  56. remainder = remainder << 1;
  57. remainder = remainder | ((dividend & (1 << i)) >> i);
  58. if((unsigned int) remainder >= (unsigned int) divisor)
  59. {
  60. remainder = remainder - divisor;
  61. quotient = quotient | 1;
  62. }
  63. if (i == 0)
  64. if (mod == 1)
  65. return remainder;
  66. else
  67. return quotient;
  68. }
  69. return 0;
  70. }
  71. // Unsigned positive integer division
  72. word MATH_divU(word dividend, word divisor)
  73. {
  74. return MATH_divmodU(dividend, divisor, 0);
  75. }
  76. // Unsigned positive integer modulo
  77. word MATH_modU(word dividend, word divisor)
  78. {
  79. return MATH_divmodU(dividend, divisor, 1);
  80. }