Graphviz
14.1.3~dev.20260207.0611
Loading...
Searching...
No Matches
sfcvt.c
Go to the documentation of this file.
1
/*************************************************************************
2
* Copyright (c) 2011 AT&T Intellectual Property
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* https://www.eclipse.org/legal/epl-v10.html
7
*
8
* Contributors: Details at https://graphviz.org
9
*************************************************************************/
10
11
#include "config.h"
12
13
#include <limits.h>
14
#include <
sfio/sfhdr.h
>
15
#include <stdio.h>
16
#include <string.h>
17
18
/* Convert a floating point value to ASCII
19
**
20
** Written by Kiem-Phong Vo
21
*/
22
23
static
char
*
Inf
=
"Inf"
, *
Zero
=
"0"
;
24
#define SF_INTPART (SF_IDIGITS/2)
25
#define SF_INFINITE ((_Sfi = 3), Inf)
26
#define SF_ZERO ((_Sfi = 1), Zero)
27
35
char
*
_sfcvt
(
void
* dv,
int
n_digit,
int
*decpt,
int
*
sign
,
int
format
)
36
{
37
char
*sp;
38
long
n, v;
39
char
*ep, *buf, *endsp;
40
static
char
Buf[
SF_MAXDIGITS
];
41
42
*
sign
= *decpt = 0;
43
{
44
double
dval = *(
double
*)dv;
45
46
if
(dval == 0.)
47
return
SF_ZERO
;
48
else
if
((*
sign
= dval < 0.))
/* assignment = */
49
dval = -dval;
50
51
n = 0;
52
if
(dval >= (
double
)LONG_MAX) {
/* scale to a small enough number to fit an int */
53
v =
SF_MAXEXP10
- 1;
54
do
{
55
if
(dval <
_Sfpos10
[v])
56
v -= 1;
57
else
{
58
dval *=
_Sfneg10
[v];
59
if
((n += 1 << v) >=
SF_IDIGITS
)
60
return
SF_INFINITE
;
61
}
62
}
while
(dval >= (
double
)LONG_MAX);
63
}
64
*decpt = (int) n;
65
66
buf = sp = Buf +
SF_INTPART
;
67
if
((v = (
int
) dval) != 0) {
/* translate the integer part */
68
dval -= (double) v;
69
70
n = snprintf(Buf,
sizeof
(Buf),
"%ld"
, v);
71
memmove(Buf +
SF_INTPART
- n, Buf, n);
72
73
if
((*decpt += (
int
) n) >=
SF_IDIGITS
)
74
return
SF_INFINITE
;
75
buf = Buf +
SF_INTPART
- n;
76
sp = Buf +
SF_INTPART
;
77
}
else
78
n = 0;
79
80
/* remaining number of digits to compute; add 1 for later rounding */
81
n = (((
format
&
SFFMT_EFORMAT
)
82
|| *decpt <= 0) ? 1 : *decpt + 1) - n;
83
if
(n_digit > 0)
84
n += n_digit;
85
86
if
((ep = sp + n) > (endsp = Buf + (
SF_MAXDIGITS
- 2)))
87
ep = endsp;
88
if
(sp > ep)
89
sp = ep;
90
else
{
91
if
((
format
&
SFFMT_EFORMAT
) && *decpt == 0 && dval > 0.) {
92
double
d;
93
while
((
int
) (d = dval * 10.) == 0) {
94
dval = d;
95
*decpt -= 1;
96
}
97
}
98
99
while
(sp < ep) {
/* generate fractional digits */
100
if
(dval <= 0.) {
/* fill with 0's */
101
do
{
102
*sp++ =
'0'
;
103
}
while
(sp < ep);
104
goto
done;
105
}
else
if
((n = (
int
) (dval *= 10.)) < 10) {
106
*sp++ = (char) (
'0'
+ n);
107
dval -= n;
108
}
else
{
/* n == 10 */
109
do
{
110
*sp++ =
'9'
;
111
}
while
(sp < ep);
112
}
113
}
114
}
115
}
116
117
if
(ep <= buf)
118
ep = buf + 1;
119
else
if
(ep < endsp) {
/* round the last digit */
120
*--sp += 5;
121
while
(*sp >
'9'
) {
122
*sp =
'0'
;
123
if
(sp > buf)
124
*--sp += 1;
125
else
{
/* next power of 10 */
126
*sp =
'1'
;
127
*decpt += 1;
128
if
(!(
format
&
SFFMT_EFORMAT
)) {
/* add one more 0 for %f precision */
129
ep[-1] =
'0'
;
130
ep += 1;
131
}
132
}
133
}
134
}
135
136
done:
137
*--ep =
'\0'
;
138
_Sfi
= ep - buf;
139
return
buf;
140
}
format
GVIO_API const char * format
Definition
gvio.h:51
sign
static int sign(double v)
Definition
legal.c:45
SF_INTPART
#define SF_INTPART
Definition
sfcvt.c:24
SF_INFINITE
#define SF_INFINITE
Definition
sfcvt.c:25
SF_ZERO
#define SF_ZERO
Definition
sfcvt.c:26
_sfcvt
char * _sfcvt(void *dv, int n_digit, int *decpt, int *sign, int format)
Definition
sfcvt.c:35
Zero
static char * Zero
Definition
sfcvt.c:23
Inf
static char * Inf
Definition
sfcvt.c:23
_Sfi
ssize_t _Sfi
Definition
sfextern.c:23
sfhdr.h
SF_MAXDIGITS
#define SF_MAXDIGITS
Definition
sfhdr.h:122
SF_IDIGITS
#define SF_IDIGITS
Definition
sfhdr.h:121
_Sfpos10
#define _Sfpos10
Definition
sfhdr.h:125
SFFMT_EFORMAT
#define SFFMT_EFORMAT
Definition
sfhdr.h:101
_Sfneg10
#define _Sfneg10
Definition
sfhdr.h:126
SF_MAXEXP10
#define SF_MAXEXP10
Definition
sfhdr.h:119
lib
sfio
sfcvt.c
Generated by
1.9.8