The R Project SVN R

Rev

Rev 24179 | Rev 29510 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 r 1
/*
466 maechler 2
 *  R : A Computer Language for Statistical Data Analysis
2 r 3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
25249 maechler 4
 *  Copyright (C) 1997--2003  The R Development Core Team.
5
 *  Copyright (C) 2003        The R Foundation
2 r 6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
5458 ripley 19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
2 r 20
 *
466 maechler 21
 *
4662 pd 22
 * Object Formatting
1839 ihaka 23
 *
2309 maechler 24
 *  See ./paste.c for do_paste() , do_format() and  do_formatinfo()
1839 ihaka 25
 *  See ./printutils.c for general remarks on Printing and the Encode.. utils.
22817 ripley 26
 *  See ./print.c  for do_printdefault, do_prmatrix, etc.
2309 maechler 27
 *
4619 maechler 28
 * Exports
4929 maechler 29
 *	formatString
4619 maechler 30
 *	formatLogical
4929 maechler 31
 *	formatFactor
4619 maechler 32
 *	formatInteger
4929 maechler 33
 *	formatReal
4619 maechler 34
 *	formatComplex
4929 maechler 35
 *
4619 maechler 36
 * These  formatFOO() functions determine the proper width, digits, etc.
2 r 37
 */
38
 
5187 hornik 39
#ifdef HAVE_CONFIG_H
7701 hornik 40
#include <config.h>
5187 hornik 41
#endif
42
 
11499 ripley 43
#include <Defn.h>
44
#include <Rmath.h>
45
#include <Print.h>
2 r 46
 
1895 ihaka 47
 
2 r 48
void formatString(SEXP *x, int n, int *fieldwidth, int quote)
49
{
18958 ripley 50
    int xmax = 0;
571 ihaka 51
    int i, l;
2 r 52
 
571 ihaka 53
    for (i = 0; i < n; i++) {
18958 ripley 54
	if (x[i] == NA_STRING) {
55
	    l = quote ? R_print.na_width : R_print.na_width_noquote;
56
	} else l = Rstrlen(CHAR(x[i]), quote) + (quote ? 2 : 0);
57
	if (l > xmax) xmax = l;
571 ihaka 58
    }
59
    *fieldwidth = xmax;
2 r 60
}
61
 
62
void formatLogical(int *x, int n, int *fieldwidth)
63
{
571 ihaka 64
    int i;
2 r 65
 
571 ihaka 66
    *fieldwidth = 1;
18958 ripley 67
    for(i = 0 ; i < n; i++) {
20509 ripley 68
	if (x[i] == NA_LOGICAL) {
69
	    if(*fieldwidth < R_print.na_width)
70
		*fieldwidth =  R_print.na_width;
71
	} else if (x[i] != 0 && *fieldwidth < 4) {
571 ihaka 72
	    *fieldwidth = 4;
20509 ripley 73
	} else if (x[i] == 0 && *fieldwidth < 5 ) {
571 ihaka 74
	    *fieldwidth = 5;
75
	    break;
19285 ripley 76
	    /* this is the widest it can be,  so stop */
2 r 77
	}
571 ihaka 78
    }
2 r 79
}
80
 
81
void formatFactor(int *x, int n, int *fieldwidth, SEXP levels, int nlevs)
82
{
571 ihaka 83
    int xmax = INT_MIN, naflag = 0;
84
    int i, l = 0;
2 r 85
 
571 ihaka 86
    if(isNull(levels)) {
87
	for(i=0 ; i<n ; i++) {
88
	    if (x[i] == NA_INTEGER || x[i] < 1 || x[i] > nlevs)
89
		naflag = 1;
90
	    else if (x[i] > xmax)
91
		xmax = x[i];
2 r 92
	}
571 ihaka 93
	if (xmax > 0)
94
	    l = IndexWidth(xmax);
95
    }
96
    else {
97
	l = 0;
98
	for(i=0 ; i<n ; i++) {
99
	    if (x[i] == NA_INTEGER || x[i] < 1 || x[i] > nlevs)
100
		naflag = 1;
101
	    else {
10172 luke 102
		xmax = strlen(CHAR(STRING_ELT(levels, x[i]-1)));
571 ihaka 103
		if (xmax > l) l = xmax;
104
	    }
2 r 105
	}
571 ihaka 106
    }
4619 maechler 107
    if (naflag) *fieldwidth = R_print.na_width;
571 ihaka 108
    else *fieldwidth = 1;
109
    if (l > *fieldwidth) *fieldwidth = l;
2 r 110
}
111
 
112
void formatInteger(int *x, int n, int *fieldwidth)
113
{
571 ihaka 114
    int xmin = INT_MAX, xmax = INT_MIN, naflag = 0;
115
    int i, l;
2 r 116
 
571 ihaka 117
    for (i = 0; i < n; i++) {
118
	if (x[i] == NA_INTEGER)
119
	    naflag = 1;
120
	else {
121
	    if (x[i] < xmin) xmin = x[i];
122
	    if (x[i] > xmax) xmax = x[i];
2 r 123
	}
571 ihaka 124
    }
2 r 125
 
4619 maechler 126
    if (naflag) *fieldwidth = R_print.na_width;
571 ihaka 127
    else *fieldwidth = 1;
2 r 128
 
571 ihaka 129
    if (xmin < 0) {
130
	l = IndexWidth(-xmin) + 1;	/* +1 for sign */
131
	if (l > *fieldwidth) *fieldwidth = l;
132
    }
133
    if (xmax > 0) {
134
	l = IndexWidth(xmax);
135
	if (l > *fieldwidth) *fieldwidth = l;
136
    }
2 r 137
}
138
 
139
/*---------------------------------------------------------------------------
140
 * scientific format determination for real numbers.
141
 * This is time-critical code.	 It is worth optimizing.
571 ihaka 142
 *
2 r 143
 *    nsig		digits altogether
144
 *    kpower+1		digits to the left of "."
145
 *    kpower+1+sgn	including sign
4619 maechler 146
 *
4929 maechler 147
 * Using GLOBAL	 R_print.digits	 -- had	 #define MAXDIG R_print.digits
4619 maechler 148
*/
2 r 149
 
19912 duncan 150
static const double tbl[] =
2 r 151
{
571 ihaka 152
    0.e0, 1.e0, 1.e1, 1.e2, 1.e3, 1.e4, 1.e5, 1.e6, 1.e7, 1.e8, 1.e9
2 r 153
};
154
 
19912 duncan 155
static void scientific(double *x, int *sgn, int *kpower, int *nsig, double eps)
2 r 156
{
25249 maechler 157
    /* for a number x , determine
571 ihaka 158
     *	sgn    = 1_{x < 0}  {0/1}
159
     *	kpower = Exponent of 10;
25249 maechler 160
     *	nsig   = min(R_print.digits, #{significant digits of alpha})
571 ihaka 161
     *
2309 maechler 162
     * where  |x| = alpha * 10^kpower	and	 1 <= alpha < 10
571 ihaka 163
     */
164
    register double alpha;
165
    register double r;
166
    register int kp;
167
    int j;
2 r 168
 
571 ihaka 169
    if (*x == 0.0) {
170
	*kpower = 0;
171
	*nsig = 1;
172
	*sgn = 0;
173
    }
174
    else {
175
	if(*x < 0.0) {
176
	    *sgn = 1; r = -*x;
177
	} else {
178
	    *sgn = 0; r = *x;
2 r 179
	}
571 ihaka 180
	kp = floor(log10(r));/*-->	 r = |x| ;  10^k <= r */
181
	if (abs(kp) < 10) {
182
	    if (kp >= 0)
183
		alpha = r / tbl[kp + 1]; /* division slow ? */
184
	    else
185
		alpha = r * tbl[-kp + 1];
186
	}
22668 ripley 187
	/* on IEEE 1e-308 is not representable except by gradual underflow.
188
	   shifting by 30 allows for any potential denormalized numbers x,
189
	   and makes the reasonable assumption that R_dec_min_exponent+30
190
	   is in range.
191
	 */
192
	else if (kp <= R_dec_min_exponent) {
193
	    alpha = (r * 1e+30)/pow(10.0, (double)(kp+30));
25249 maechler 194
	}
195
	else
22661 ripley 196
	    alpha = r / pow(10.0, (double)kp);
2 r 197
 
10358 ripley 198
	/* make sure that alpha is in [1,10) AFTER rounding */
2 r 199
 
10358 ripley 200
	if (10.0 - alpha < eps*alpha) {
571 ihaka 201
	    alpha /= 10.0;
202
	    kp += 1;
203
	}
204
	*kpower = kp;
2 r 205
 
571 ihaka 206
	/* compute number of digits */
2 r 207
 
4619 maechler 208
	*nsig = R_print.digits;
571 ihaka 209
	for (j=1; j <= *nsig; j++) {
210
	    if (fabs(alpha - floor(alpha+0.5)) < eps * alpha) {
211
		*nsig = j;
212
		break;
213
	    }
214
	    alpha *= 10.0;
2 r 215
	}
571 ihaka 216
    }
2 r 217
}
218
 
14357 ripley 219
void formatReal(double *x, int l, int *m, int *n, int *e, int nsmall)
2 r 220
{
571 ihaka 221
    int left, right, sleft;
10866 maechler 222
    int mnl, mxl, rgt, mxsl, mxns, mF;
571 ihaka 223
    int neg, sgn, kpower, nsig;
580 ihaka 224
    int i, naflag, nanflag, posinf, neginf;
2 r 225
 
19912 duncan 226
    double eps = pow(10.0, -(double)R_print.digits);
2 r 227
 
580 ihaka 228
    nanflag = 0;
571 ihaka 229
    naflag = 0;
230
    posinf = 0;
231
    neginf = 0;
232
    neg = 0;
10866 maechler 233
    rgt = mxl = mxsl = mxns = INT_MIN;
571 ihaka 234
    mnl = INT_MAX;
2 r 235
 
571 ihaka 236
    for (i=0; i<l; i++) {
5107 maechler 237
	if (!R_FINITE(x[i])) {
580 ihaka 238
	    if(ISNA(x[i])) naflag = 1;
239
	    else if(ISNAN(x[i])) nanflag = 1;
571 ihaka 240
	    else if(x[i] > 0) posinf = 1;
241
	    else neginf = 1;
242
	} else {
19912 duncan 243
	    scientific(&x[i], &sgn, &kpower, &nsig, eps);
466 maechler 244
 
571 ihaka 245
	    left = kpower + 1;
246
	    sleft = sgn + ((left <= 0) ? 1 : left); /* >= 1 */
247
	    right = nsig - left; /* #{digits} right of '.' ( > 0 often)*/
2309 maechler 248
	    if (sgn) neg = 1;	 /* if any < 0, need extra space for sign */
466 maechler 249
 
571 ihaka 250
	    /* Infinite precision "F" Format : */
10866 maechler 251
	    if (right > rgt) rgt = right;	/* max digits to right of . */
252
	    if (left > mxl)  mxl = left;	/* max digits to  left of . */
253
	    if (left < mnl)  mnl = left;	/* min digits to  left of . */
254
	    if (sleft> mxsl) mxsl = sleft;	/* max left including sign(s)*/
255
	    if (nsig > mxns) mxns = nsig;	/* max sig digits */
2 r 256
	}
571 ihaka 257
    }
25249 maechler 258
    /* F Format: use "F" format WHENEVER we use not more space than 'E'
259
     *		and still satisfy 'R_print.digits' {but as if nsmall==0 !}
1839 ihaka 260
     *
571 ihaka 261
     * E Format has the form   [S]X[.XXX]E+XX[X]
262
     *
263
     * This is indicated by setting *e to non-zero (usually 1)
264
     * If the additional exponent digit is required *e is set to 2
265
     */
2 r 266
 
25249 maechler 267
    /*-- These	'mxsl' & 'rgt'	are used in F Format
10866 maechler 268
     *	 AND in the	____ if(.) "F" else "E" ___   below: */
571 ihaka 269
    if (mxl < 0) mxsl = 1 + neg;
25249 maechler 270
 
271
    /* use nsmall only *after* comparing "F" vs "E": */
272
    if (rgt < 0) rgt = 0;
10866 maechler 273
    mF = mxsl + rgt + (rgt != 0);	/* width m for F  format */
2 r 274
 
10866 maechler 275
    /*-- 'see' how "E" Exponential format would be like : */
571 ihaka 276
    if (mxl > 100 || mnl < -99) *e = 2;/* 3 digit exponent */
277
    else *e = 1;
278
    *n = mxns - 1;
2309 maechler 279
    *m = neg + (*n > 0) + *n + 4 + *e; /* width m for E	 format */
466 maechler 280
 
24179 ripley 281
    if (mF <= *m  + R_print.scipen) { /* Fixpoint if it needs less space */
571 ihaka 282
	*e = 0;
25249 maechler 283
	if (nsmall > rgt) {
284
	    rgt = nsmall;
285
	    mF = mxsl + rgt + (rgt != 0);
286
	}
10866 maechler 287
	*n = rgt;
571 ihaka 288
	*m = mF;
289
    } /* else : "E" Exponential format -- all done above */
4619 maechler 290
    if (naflag && *m < R_print.na_width)
291
	*m = R_print.na_width;
580 ihaka 292
    if (nanflag && *m < 3) *m = 3;
571 ihaka 293
    if (posinf && *m < 3) *m = 3;
294
    if (neginf && *m < 4) *m = 4;
2 r 295
}
296
 
580 ihaka 297
 
6994 pd 298
void formatComplex(Rcomplex *x, int l, int *mr, int *nr, int *er,
14357 ripley 299
		   int *mi, int *ni, int *ei, int nsmall)
2 r 300
{
5055 pd 301
/* format.info() or  x[1..l] for both Re & Im */
580 ihaka 302
    int left, right, sleft;
303
    int rt, mnl, mxl, mxsl, mxns, mF;
304
    int i_rt, i_mnl, i_mxl, i_mxsl, i_mxns;
305
    int neg, sgn;
306
    int i, kpower, nsig;
307
    int naflag;
4929 maechler 308
    int rnanflag, rposinf, rneginf, inanflag, iposinf;
2 r 309
 
19912 duncan 310
    double eps = pow(10.0, -(double)R_print.digits);
2 r 311
 
580 ihaka 312
    naflag = 0;
313
    rnanflag = 0;
314
    rposinf = 0;
315
    rneginf = 0;
316
    inanflag = 0;
317
    iposinf = 0;
318
    neg = 0;
2 r 319
 
2309 maechler 320
    rt	=  mxl =  mxsl =  mxns = INT_MIN;
580 ihaka 321
    i_rt= i_mxl= i_mxsl= i_mxns= INT_MIN;
322
    i_mnl = mnl = INT_MAX;
2 r 323
 
580 ihaka 324
    for (i=0; i<l; i++) {
2 r 325
 
580 ihaka 326
	if(ISNA(x[i].r) || ISNA(x[i].i)) {
327
	    naflag = 1;
328
	}
329
	else {
1016 maechler 330
 
571 ihaka 331
	    /* real part */
332
 
5107 maechler 333
	    if(!R_FINITE(x[i].r)) {
580 ihaka 334
		if (ISNAN(x[i].r)) rnanflag = 1;
335
		else if (x[i].r > 0) rposinf = 1;
336
		else rneginf = 1;
571 ihaka 337
	    }
1404 maechler 338
	    else
339
	      {
19912 duncan 340
		scientific(&(x[i].r), &sgn, &kpower, &nsig, eps);
2 r 341
 
342
		left = kpower + 1;
343
		sleft = sgn + ((left <= 0) ? 1 : left); /* >= 1 */
344
		right = nsig - left; /* #{digits} right of '.' ( > 0 often)*/
345
		if (sgn) neg = 1; /* if any < 0, need extra space for sign */
346
 
347
		if (right > rt) rt = right;	/* max digits to right of . */
348
		if (left > mxl) mxl = left;	/* max digits to left of . */
349
		if (left < mnl) mnl = left;	/* min digits to left of . */
350
		if (sleft> mxsl) mxsl = sleft;	/* max left including sign(s) */
351
		if (nsig > mxns) mxns = nsig;	/* max sig digits */
352
 
571 ihaka 353
	    }
580 ihaka 354
	    /* imaginary part */
571 ihaka 355
 
580 ihaka 356
	    /* this is always unsigned */
357
	    /* we explicitly put the sign in when we print */
466 maechler 358
 
5107 maechler 359
	    if(!R_FINITE(x[i].i)) {
580 ihaka 360
		if (ISNAN(x[i].i)) inanflag = 1;
361
		else iposinf = 1;
571 ihaka 362
	    }
2309 maechler 363
	    else
1404 maechler 364
	      {
19912 duncan 365
		scientific(&(x[i].i), &sgn, &kpower, &nsig, eps);
466 maechler 366
 
2 r 367
		left = kpower + 1;
368
		sleft = ((left <= 0) ? 1 : left);
369
		right = nsig - left;
466 maechler 370
 
2 r 371
		if (right > i_rt) i_rt = right;
372
		if (left > i_mxl) i_mxl = left;
373
		if (left < i_mnl) i_mnl = left;
374
		if (sleft> i_mxsl) i_mxsl = sleft;
375
		if (nsig > i_mxns) i_mxns = nsig;
571 ihaka 376
	    }
1016 maechler 377
	    /* done: ; */
2 r 378
	}
580 ihaka 379
    }
2 r 380
 
580 ihaka 381
    /* see comments in formatReal() for details on this */
2 r 382
 
580 ihaka 383
    /* overall format for real part	*/
2 r 384
 
580 ihaka 385
    if (mxl != INT_MIN) {
2 r 386
	if (mxl < 0) mxsl = 1 + neg;
25249 maechler 387
	if (rt < 0) rt = 0;
2 r 388
	mF = mxsl + rt + (rt != 0);
389
 
390
	if (mxl > 100 || mnl < -99) *er = 2;
391
	else *er = 1;
392
	*nr = mxns - 1;
393
	*mr = neg + (*nr > 0) + *nr + 4 + *er;
24179 ripley 394
        if (mF <= *mr + R_print.scipen) { /* Fixpoint if it needs less space */
580 ihaka 395
	    *er = 0;
25249 maechler 396
	    if (nsmall > rt) {
397
		rt = nsmall;
398
		mF = mxsl + rt + (rt != 0);
399
	    }
580 ihaka 400
	    *nr = rt;
401
	    *mr = mF;
2 r 402
	}
580 ihaka 403
    }
404
    else {
405
	*er = 0;
406
	*mr = 0;
407
	*nr = 0;
408
    }
409
    if (rnanflag && *mr < 3) *mr = 3;
410
    if (rposinf && *mr < 3) *mr = 3;
411
    if (rneginf && *mr < 4) *mr = 4;
2 r 412
 
580 ihaka 413
    /* overall format for imaginary part */
2 r 414
 
580 ihaka 415
    if (i_mxl != INT_MIN) {
2 r 416
	if (i_mxl < 0) i_mxsl = 1;
25249 maechler 417
	if (i_rt < 0) i_rt = 0;
2 r 418
	mF = i_mxsl + i_rt + (i_rt != 0);
419
 
420
	if (i_mxl > 100 || i_mnl < -99) *ei = 2;
421
	else *ei = 1;
422
	*ni = i_mxns - 1;
423
	*mi = (*ni > 0) + *ni + 4 + *ei;
24179 ripley 424
        if (mF <= *mi + R_print.scipen) { /* Fixpoint if it needs less space */
580 ihaka 425
	    *ei = 0;
25249 maechler 426
	    if (nsmall > i_rt) {
427
		i_rt = nsmall;
428
		mF = mxsl + i_rt + (i_rt != 0);
429
	    }
580 ihaka 430
	    *ni = i_rt;
431
	    *mi = mF;
2 r 432
	}
580 ihaka 433
    }
434
    else {
435
	*ei = 0;
436
	*mi = 0;
437
	*ni = 0;
438
    }
4929 maechler 439
    if (inanflag && *mi < 3) *mi = 3;
5055 pd 440
    if (iposinf  && *mi < 3) *mi = 3;
580 ihaka 441
    if(*mr < 0) *mr = 0;
442
    if(*mi < 0) *mi = 0;
443
 
444
    /* finally, ensure that there is space for NA */
445
 
4619 maechler 446
    if (naflag && *mr+*mi+2 < R_print.na_width)
447
	*mr += (R_print.na_width -(*mr + *mi + 2));
2 r 448
}