xround.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include <limits.h>
  2. #include <grass/gis.h>
  3. #include <grass/raster.h>
  4. #include "globals.h"
  5. #include "expression.h"
  6. #include "func_proto.h"
  7. /**********************************************************************
  8. round(x)
  9. rounds x to nearest integer.
  10. if input is CELL (which is an integer already)
  11. the input argument (argv[0]) is simply copied to the output cell.
  12. if the input is double, the input is rounded by adding .5 to positive
  13. numbers, and subtracting .5 from negatives.
  14. **********************************************************************/
  15. /* i_round(x) rounds x to nearest CELL value, handles negative correctly */
  16. static int i_round(double x)
  17. {
  18. int n;
  19. if (IS_NULL_D(&x))
  20. SET_NULL_C(&n);
  21. else if (x > INT_MAX || x < -INT_MAX) {
  22. SET_NULL_C(&n);
  23. if (!IS_NULL_D(&x))
  24. overflow_occurred = 1;
  25. }
  26. else if (x >= 0.0)
  27. n = x + .5;
  28. else {
  29. n = -x + .5;
  30. n = -n;
  31. }
  32. return n;
  33. }
  34. /**********************************************************************/
  35. int f_round(int argc, const int *argt, void **args)
  36. {
  37. int *res = args[0];
  38. int i;
  39. if (argc < 1)
  40. return E_ARG_LO;
  41. if (argc > 1)
  42. return E_ARG_HI;
  43. if (argt[0] != CELL_TYPE)
  44. return E_RES_TYPE;
  45. switch (argt[1]) {
  46. case CELL_TYPE:
  47. {
  48. CELL *arg1 = args[1];
  49. for (i = 0; i < columns; i++)
  50. if (IS_NULL_C(&arg1[i]))
  51. SET_NULL_C(&res[i]);
  52. else
  53. res[i] = arg1[i];
  54. return 0;
  55. }
  56. case FCELL_TYPE:
  57. {
  58. FCELL *arg1 = args[1];
  59. for (i = 0; i < columns; i++)
  60. if (IS_NULL_F(&arg1[i]))
  61. SET_NULL_C(&res[i]);
  62. else
  63. res[i] = i_round(arg1[i]);
  64. return 0;
  65. }
  66. case DCELL_TYPE:
  67. {
  68. DCELL *arg1 = args[1];
  69. for (i = 0; i < columns; i++)
  70. if (IS_NULL_D(&arg1[i]))
  71. SET_NULL_C(&res[i]);
  72. else
  73. res[i] = i_round(arg1[i]);
  74. return 0;
  75. }
  76. default:
  77. return E_INV_TYPE;
  78. }
  79. }
  80. int c_round(int argc, int *argt)
  81. {
  82. if (argc < 1)
  83. return E_ARG_LO;
  84. if (argc > 1)
  85. return E_ARG_HI;
  86. argt[0] = CELL_TYPE;
  87. /* argt[1] = argt[1]; */
  88. return 0;
  89. }