summaryrefslogtreecommitdiff
path: root/support/dktools/dk4numl.ctr
blob: 5e97883bca4789c96356143ae001c5a03600455e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
%%	options

copyright owner	=	Dirk Krause
copyright year	=	2015-xxxx
license		=	bsd



%%	header

/**	@file
	Text representation length for numbers.
	When showing information in a table one needs to know the length
	of each field.
	This module provides the dk4numlength() funtion to find the string
	length needed for an integer value of a given size (number of bytes).

	CRT on Windows: Not used.
*/

#ifndef DK4CONF_H_INCLUDED
#include "dk4conf.h"
#endif

#ifndef DK4TYPES_H_INCLUDED
#include "dk4types.h"
#endif


#ifdef __cplusplus
extern "C" {
#endif

/**	Find number of digits for data type.
	@param	isz	Integer data type size in bytes.
	@param	sgn	Flag: Signed data type (0=unsigned, other=signed).
	@return	Maximum string length used when data is shown as text.
*/
size_t
dk4numlength(size_t isz, int sgn);

#ifdef __cplusplus
}
#endif

%%	module

#include "dk4conf.h"
#include "dk4error.h"
#include "dk4numl.h"
#include "dk4maadu.h"

size_t
dk4numlength(size_t isz, int sgn)
{
  dk4_er_t	er;
  dk4_um_t	co;
  size_t	back	=	0;
  if (1 < isz) {
    if (2 < isz) {
      if (4 < isz) {
        if (8 < isz) {
	  if (16 < isz) {
#if VERSION_BEFORE_20141122
	    if (0 != (isz % 2)) { isz++; }
	    back = 5 * (isz / 2);
	    if (0 != sgn) { back++; }
#else
	    dk4error_init(&er);
	    if (0 != sgn) {
	      co = dk4ma_um_mul(
	        (dk4_um_t)30104UL,
		dk4ma_um_sub(
		  dk4ma_um_mul((dk4_um_t)8UL, (dk4_um_t)isz, &er),
		  (dk4_um_t)1UL,
		  &er
		),
		&er
	      );
	      if ((dk4_um_t)0UL != (co % (dk4_um_t)100000UL)) {
	        co = co / (dk4_um_t)100000UL;
		co++;
	      } else {
	        co = co / (dk4_um_t)100000UL;
	      }
	      co++;
	      if ((dk4_um_t)(SIZE_MAX) >= co) {
	        back = (size_t)co;
	      } else {
	        back = (size_t)co;
		er.ec = DK4_E_MATH_OVERFLOW;
	      }
	    } else {
	      co = dk4ma_um_mul(
	        (dk4_um_t)30104UL,
		dk4ma_um_mul((dk4_um_t)8UL, (dk4_um_t)isz, &er),
		&er
	      );
	      if ((dk4_um_t)0UL != (co % (dk4_um_t)100000UL)) {
	        co = co / (dk4_um_t)100000UL;
		co++;
	      } else {
	        co = co / (dk4_um_t)100000UL;
	      }
	      if ((dk4_um_t)(SIZE_MAX) >= co) {
	        back = (size_t)co;
	      } else {
	        back = (size_t)co;
		er.ec = DK4_E_MATH_OVERFLOW;
	      }
	    }
	    if (DK4_E_NONE != er.ec) {
	      if (0 != (isz % 2)) { isz++; }
	      back = 5 * (isz / 2);
	      if (0 != sgn) { back++; }
	    }
#endif
	  } else {
	    back = ((0 != sgn) ? 41 : 40);
	  }
	} else {
	  back = ((0 != sgn) ? 21 : 20);
	}
      } else {
        back = ((0 != sgn) ? 11 : 10);
      }
    } else {
      back = ((0 != sgn) ? 6 : 5);
    }
  } else {
    back = ((0 != sgn) ? 4 : 3);
  }
  return back;
}