Changeset 56313


Ignore:
Timestamp:
May 19, 2013, 6:30:36 AM (11 years ago)
Author:
mmetz
Message:

r.mapcalc: enhance round()

Location:
grass/trunk/raster/r.mapcalc
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • grass/trunk/raster/r.mapcalc/function.c

    r52178 r56313  
    9090    {"nsres", c_double0, f_nsres},
    9191    {"tbres", c_double0, f_tbres},
    92     {NULL}
     92    {NULL, NULL, NULL}
    9393};
    9494
  • grass/trunk/raster/r.mapcalc/r.mapcalc.html

    r54965 r56313  
    319319pow(x,y)                x to the power y                                *
    320320rand(a,b)               random value x : a <= x < b
    321 round(x)                round x to nearest integer                      I
     321round(x)                round x to nearest integer                      *
     322round(x, y)             round x to y decimal places                     *
    322323sin(x)                  sine of x (x is in degrees)                     F
    323324sqrt(x)                 square root of x                                F
     
    336337</pre></div>
    337338Note, that the row() and col() indexing starts with 1.
     339<p>
     340round(x, y) supports a negative number of decimal places: for example,
     341round(119, -1) results in 120, and round(119, -2) results in 100.
    338342
    339343
  • grass/trunk/raster/r.mapcalc/r3.mapcalc.html

    r54965 r56313  
    223223pow(x,y)                x to the power y                                *
    224224rand(a,b)               random value x : a &lt;= x &lt; b
    225 round(x)                round x to nearest integer                      I
     225round(x)                round x to nearest integer                      *
     226round(x, y)             round x to y decimal places                     *
    226227sin(x)                  sine of x (x is in degrees)                     F
    227228sqrt(x)                 square root of x                                F
     
    243244</pre></div>
    244245Note, that the row(), col() and depth() indexing starts with 1.
     246<p>
     247round(x, y) supports a negative number of decimal places: for example,
     248round(119, -1) results in 120, and round(119, -2) results in 100.
    245249
    246250
  • grass/trunk/raster/r.mapcalc/xround.c

    r39130 r56313  
    11
    22#include <limits.h>
     3#include <math.h>
    34
    45#include <grass/gis.h>
     
    910
    1011/**********************************************************************
    11 round(x)
    12 
    13   rounds x to nearest integer.
     12round(x) rounds x to nearest integer
     13round(x, y) rounds x to y decimal places
    1414
    1515  if input is CELL (which is an integer already)
     16  and the number of decimal places is 0
    1617  the input argument (argv[0]) is simply copied to the output cell.
    1718
     
    2021**********************************************************************/
    2122
    22 /* i_round(x) rounds x to nearest CELL value, handles negative correctly */
    23 
    24 static int i_round(double x)
    25 {
    26     int n;
    27 
    28     if (IS_NULL_D(&x))
    29         SET_NULL_C(&n);
    30     else if (x > INT_MAX || x < -INT_MAX) {
    31         SET_NULL_C(&n);
    32         if (!IS_NULL_D(&x))
    33             overflow_occurred = 1;
    34     }
    35     else if (x >= 0.0)
    36         n = x + .5;
    37     else {
    38         n = -x + .5;
    39         n = -n;
    40     }
    41 
    42     return n;
     23/* d_round(x) rounds x to nearest integer value, handles negative correctly */
     24
     25static double d_round(double x)
     26{
     27    if (!IS_NULL_D(&x)) {
     28        x = floor(x + 0.5);
     29    }
     30
     31    return x;
    4332}
    4433
    4534/**********************************************************************/
    4635
     36/* d_roundd(x, y) rounds x to y decimal places, handles negative correctly */
     37
     38static double d_roundd(double x, int y)
     39{
     40    if (!IS_NULL_D(&x)) {
     41        double pow10, intx, sgn = 1.;
     42
     43        if (x < 0.) {
     44            sgn = -1.;
     45            x = -x;
     46        }
     47        if (y == 0)
     48            return (double)(sgn * d_round(x));
     49        else if (y > 0) {
     50            pow10 = pow(10., y);
     51            intx = floor(x);
     52            return (double)(sgn * (intx + d_round((double)((x - intx) * pow10)) / pow10));
     53        }
     54        else {
     55            pow10 = pow(10., -y);
     56            return (double)(sgn * d_round((double)(x / pow10)) * pow10);
     57        }
     58    }
     59
     60    return x;
     61}
     62
     63/**********************************************************************/
    4764int f_round(int argc, const int *argt, void **args)
    4865{
    49     int *res = args[0];
    5066    int i;
    5167
    5268    if (argc < 1)
    5369        return E_ARG_LO;
    54     if (argc > 1)
     70    if (argc > 2)
    5571        return E_ARG_HI;
    5672
    57     if (argt[0] != CELL_TYPE)
    58         return E_RES_TYPE;
    59 
    60     switch (argt[1]) {
    61     case CELL_TYPE:
    62         {
    63             CELL *arg1 = args[1];
    64 
    65             for (i = 0; i < columns; i++)
    66                 if (IS_NULL_C(&arg1[i]))
    67                     SET_NULL_C(&res[i]);
    68                 else
    69                     res[i] = arg1[i];
    70             return 0;
    71         }
    72     case FCELL_TYPE:
    73         {
    74             FCELL *arg1 = args[1];
    75 
    76             for (i = 0; i < columns; i++)
    77                 if (IS_NULL_F(&arg1[i]))
    78                     SET_NULL_C(&res[i]);
    79                 else
    80                     res[i] = i_round(arg1[i]);
    81             return 0;
    82         }
    83     case DCELL_TYPE:
    84         {
    85             DCELL *arg1 = args[1];
    86 
    87             for (i = 0; i < columns; i++)
    88                 if (IS_NULL_D(&arg1[i]))
    89                     SET_NULL_C(&res[i]);
    90                 else
    91                     res[i] = i_round(arg1[i]);
    92             return 0;
    93         }
    94     default:
    95         return E_INV_TYPE;
     73    if (argc == 1) {
     74        switch (argt[1]) {
     75        case CELL_TYPE:
     76            {
     77                CELL *arg1 = args[1];
     78                CELL *res = args[0];
     79
     80                for (i = 0; i < columns; i++)
     81                    if (IS_NULL_C(&arg1[i]))
     82                        SET_NULL_C(&res[i]);
     83                    else
     84                        res[i] = arg1[i];
     85                return 0;
     86            }
     87        case FCELL_TYPE:
     88            {
     89                FCELL *arg1 = args[1];
     90                FCELL *res = args[0];
     91
     92                for (i = 0; i < columns; i++)
     93                    if (IS_NULL_F(&arg1[i]))
     94                        SET_NULL_F(&res[i]);
     95                    else
     96                        res[i] = d_round(arg1[i]);
     97                return 0;
     98            }
     99        case DCELL_TYPE:
     100            {
     101                DCELL *arg1 = args[1];
     102                DCELL *res = args[0];
     103
     104                for (i = 0; i < columns; i++)
     105                    if (IS_NULL_D(&arg1[i]))
     106                        SET_NULL_D(&res[i]);
     107                    else
     108                        res[i] = d_round(arg1[i]);
     109                return 0;
     110            }
     111        default:
     112            return E_INV_TYPE;
     113        }
     114    }
     115    else {    /* argc == 2 */
     116        int digits;
     117        DCELL *arg2;
     118
     119        switch (argt[1]) {
     120        case CELL_TYPE:
     121            {
     122                CELL *arg1 = args[1];
     123                CELL *res = args[0];
     124
     125                arg2 = args[2];
     126
     127                for (i = 0; i < columns; i++)
     128                    if (IS_NULL_C(&arg1[i]))
     129                        SET_NULL_C(&res[i]);
     130                    else {
     131                        if (arg2[i] >= 0)
     132                            digits = d_round(arg2[i]) + 0.5;
     133                        else
     134                            digits = d_round(arg2[i]) - 0.5;
     135                        if (digits >= 0)
     136                            res[i] = arg1[i];
     137                        else {
     138                            if (arg1[i] >= 0)
     139                                res[i] = d_roundd(arg1[i], digits) + 0.5;
     140                            else
     141                                res[i] = d_roundd(arg1[i], digits) - 0.5;
     142                        }
     143                    }
     144                return 0;
     145            }
     146        case FCELL_TYPE:
     147            {
     148                FCELL *arg1 = args[1];
     149                FCELL *res = args[0];
     150
     151                arg2 = args[2];
     152
     153                for (i = 0; i < columns; i++)
     154                    if (IS_NULL_F(&arg1[i]))
     155                        SET_NULL_F(&res[i]);
     156                    else {
     157                        if (arg2[i] >= 0)
     158                            digits = d_round(arg2[i]) + 0.5;
     159                        else
     160                            digits = d_round(arg2[i]) - 0.5;
     161                        res[i] = d_roundd(arg1[i], digits);
     162                    }
     163                return 0;
     164            }
     165        case DCELL_TYPE:
     166            {
     167                DCELL *arg1 = args[1];
     168                DCELL *res = args[0];
     169
     170                arg2 = args[2];
     171
     172                for (i = 0; i < columns; i++)
     173                    if (IS_NULL_D(&arg1[i]))
     174                        SET_NULL_D(&res[i]);
     175                    else {
     176                        if (arg2[i] >= 0)
     177                            digits = d_round(arg2[i]) + 0.5;
     178                        else
     179                            digits = d_round(arg2[i]) - 0.5;
     180                        res[i] = d_roundd(arg1[i], digits);
     181                    }
     182                return 0;
     183            }
     184        default:
     185            return E_INV_TYPE;
     186        }
    96187    }
    97188}
     
    101192    if (argc < 1)
    102193        return E_ARG_LO;
    103     if (argc > 1)
     194    if (argc > 2)
    104195        return E_ARG_HI;
    105196
    106     argt[0] = CELL_TYPE;
    107     /*      argt[1] = argt[1];      */
     197    argt[0] = argt[1];
     198   
     199    if (argc == 2)
     200        argt[2] = DCELL_TYPE;
    108201
    109202    return 0;
Note: See TracChangeset for help on using the changeset viewer.