math.c 2.3 KB

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