xpow.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include <math.h>
  2. #include <grass/gis.h>
  3. #include <grass/raster.h>
  4. #include <grass/calc.h>
  5. /****************************************************************
  6. pow(a,b)
  7. a raised to the power b
  8. ****************************************************************/
  9. static int ipow(int x, int y)
  10. {
  11. int res = 1;
  12. while (y) {
  13. if (y & 1)
  14. res *= x;
  15. y >>= 1;
  16. x *= x;
  17. }
  18. return res;
  19. }
  20. int f_pow(int argc, const int *argt, void **args)
  21. {
  22. int i;
  23. if (argc < 2)
  24. return E_ARG_LO;
  25. if (argc > 2)
  26. return E_ARG_HI;
  27. if (argt[1] != argt[0] || argt[2] != argt[0])
  28. return E_ARG_TYPE;
  29. switch (argt[0]) {
  30. case CELL_TYPE:
  31. {
  32. CELL *res = args[0];
  33. CELL *arg1 = args[1];
  34. CELL *arg2 = args[2];
  35. for (i = 0; i < columns; i++) {
  36. if (IS_NULL_C(&arg1[i]) || IS_NULL_C(&arg2[i]) || arg2[i] < 0)
  37. SET_NULL_C(&res[i]);
  38. else
  39. res[i] = ipow(arg1[i], arg2[i]);
  40. }
  41. return 0;
  42. }
  43. case FCELL_TYPE:
  44. {
  45. FCELL *res = args[0];
  46. FCELL *arg1 = args[1];
  47. FCELL *arg2 = args[2];
  48. for (i = 0; i < columns; i++) {
  49. if (IS_NULL_F(&arg1[i]) || IS_NULL_F(&arg2[i]))
  50. SET_NULL_F(&res[i]);
  51. else if (arg1[i] < 0 && arg2[i] != ceil(arg2[i]))
  52. SET_NULL_F(&res[i]);
  53. else {
  54. floating_point_exception = 0;
  55. res[i] = pow(arg1[i], arg2[i]);
  56. if (floating_point_exception)
  57. SET_NULL_F(&res[i]);
  58. }
  59. }
  60. return 0;
  61. }
  62. case DCELL_TYPE:
  63. {
  64. DCELL *res = args[0];
  65. DCELL *arg1 = args[1];
  66. DCELL *arg2 = args[2];
  67. for (i = 0; i < columns; i++) {
  68. if (IS_NULL_D(&arg1[i]) || IS_NULL_D(&arg2[i]))
  69. SET_NULL_D(&res[i]);
  70. else if (arg1[i] < 0 && arg2[i] != ceil(arg2[i]))
  71. SET_NULL_D(&res[i]);
  72. else {
  73. floating_point_exception = 0;
  74. res[i] = pow(arg1[i], arg2[i]);
  75. if (floating_point_exception)
  76. SET_NULL_D(&res[i]);
  77. }
  78. }
  79. return 0;
  80. }
  81. default:
  82. return E_INV_TYPE;
  83. }
  84. }