Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
74958219
Commit
74958219
authored
Jul 23, 2020
by
Piotr Caban
Committed by
Alexandre Julliard
Jul 23, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Support arbitrary buffer size in bnum.
Signed-off-by:
Piotr Caban
<
piotr@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
413e34df
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
112 additions
and
100 deletions
+112
-100
bnum.h
dlls/msvcrt/bnum.h
+29
-22
printf.h
dlls/msvcrt/printf.h
+51
-48
string.c
dlls/msvcrt/string.c
+32
-30
No files found.
dlls/msvcrt/bnum.h
View file @
74958219
...
...
@@ -26,19 +26,26 @@ static const int p10s[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
#define LIMB_DIGITS 9
/* each DWORD stores up to 9 digits */
#define LIMB_MAX 1000000000
/* 10^9 */
#define BNUM_IDX(i) ((i) & 127)
#define BNUM_PREC64 128
/* data size needed to store 64-bit double */
/* bnum represents real number with fixed decimal point (after 2 limbs) */
struct
bnum
{
DWORD
data
[
128
];
/* circular buffer, base 10 number */
int
b
;
/* least significant digit position */
int
e
;
/* most significant digit position + 1 */
int
size
;
/* data buffer size in DWORDS (power of 2) */
DWORD
data
[
1
];
/* circular buffer, base 10 number */
};
static
inline
int
bnum_idx
(
struct
bnum
*
b
,
int
idx
)
{
return
idx
&
(
b
->
size
-
1
);
}
/* Returns integral part of bnum */
static
inline
ULONGLONG
bnum_to_mant
(
struct
bnum
*
b
)
{
ULONGLONG
ret
=
(
ULONGLONG
)
b
->
data
[
BNUM_IDX
(
b
->
e
-
1
)]
*
LIMB_MAX
;
if
(
b
->
b
!=
b
->
e
-
1
)
ret
+=
b
->
data
[
BNUM_IDX
(
b
->
e
-
2
)];
ULONGLONG
ret
=
(
ULONGLONG
)
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]
*
LIMB_MAX
;
if
(
b
->
b
!=
b
->
e
-
1
)
ret
+=
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
2
)];
return
ret
;
}
...
...
@@ -53,20 +60,20 @@ static inline BOOL bnum_lshift(struct bnum *b, int shift)
assert
(
shift
<=
29
);
for
(
i
=
b
->
b
;
i
<
b
->
e
;
i
++
)
{
tmp
=
((
ULONGLONG
)
b
->
data
[
BNUM_IDX
(
i
)]
<<
shift
)
+
rest
;
tmp
=
((
ULONGLONG
)
b
->
data
[
bnum_idx
(
b
,
i
)]
<<
shift
)
+
rest
;
rest
=
tmp
/
LIMB_MAX
;
b
->
data
[
BNUM_IDX
(
i
)]
=
tmp
%
LIMB_MAX
;
b
->
data
[
bnum_idx
(
b
,
i
)]
=
tmp
%
LIMB_MAX
;
if
(
i
==
b
->
b
&&
!
b
->
data
[
BNUM_IDX
(
i
)])
if
(
i
==
b
->
b
&&
!
b
->
data
[
bnum_idx
(
b
,
i
)])
b
->
b
++
;
}
if
(
rest
)
{
b
->
data
[
BNUM_IDX
(
b
->
e
)]
=
rest
;
b
->
data
[
bnum_idx
(
b
,
b
->
e
)]
=
rest
;
b
->
e
++
;
if
(
BNUM_IDX
(
b
->
b
)
==
BNUM_IDX
(
b
->
e
))
{
if
(
b
->
data
[
BNUM_IDX
(
b
->
b
)])
b
->
data
[
BNUM_IDX
(
b
->
b
+
1
)]
|=
1
;
if
(
bnum_idx
(
b
,
b
->
b
)
==
bnum_idx
(
b
,
b
->
e
))
{
if
(
b
->
data
[
bnum_idx
(
b
,
b
->
b
)])
b
->
data
[
bnum_idx
(
b
,
b
->
b
+
1
)]
|=
1
;
b
->
b
++
;
}
return
TRUE
;
...
...
@@ -85,21 +92,21 @@ static inline BOOL bnum_rshift(struct bnum *b, int shift)
assert
(
shift
<=
9
);
for
(
i
=
b
->
e
-
1
;
i
>=
b
->
b
;
i
--
)
{
tmp
=
b
->
data
[
BNUM_IDX
(
i
)]
&
((
1
<<
shift
)
-
1
);
b
->
data
[
BNUM_IDX
(
i
)]
=
(
b
->
data
[
BNUM_IDX
(
i
)]
>>
shift
)
+
rest
;
tmp
=
b
->
data
[
bnum_idx
(
b
,
i
)]
&
((
1
<<
shift
)
-
1
);
b
->
data
[
bnum_idx
(
b
,
i
)]
=
(
b
->
data
[
bnum_idx
(
b
,
i
)]
>>
shift
)
+
rest
;
rest
=
(
LIMB_MAX
>>
shift
)
*
tmp
;
if
(
i
==
b
->
e
-
1
&&
!
b
->
data
[
BNUM_IDX
(
i
)])
{
if
(
i
==
b
->
e
-
1
&&
!
b
->
data
[
bnum_idx
(
b
,
i
)])
{
b
->
e
--
;
ret
=
TRUE
;
}
}
if
(
rest
)
{
if
(
BNUM_IDX
(
b
->
b
-
1
)
==
BNUM_IDX
(
b
->
e
))
{
if
(
rest
)
b
->
data
[
BNUM_IDX
(
b
->
b
)]
|=
1
;
if
(
bnum_idx
(
b
,
b
->
b
-
1
)
==
bnum_idx
(
b
,
b
->
e
))
{
if
(
rest
)
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
|=
1
;
}
else
{
b
->
b
--
;
b
->
data
[
BNUM_IDX
(
b
->
b
)]
=
rest
;
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
=
rest
;
}
}
return
ret
;
...
...
@@ -114,20 +121,20 @@ static inline void bnum_mult(struct bnum *b, int mult)
assert
(
mult
<=
LIMB_MAX
);
for
(
i
=
b
->
b
;
i
<
b
->
e
;
i
++
)
{
tmp
=
((
ULONGLONG
)
b
->
data
[
BNUM_IDX
(
i
)]
*
mult
)
+
rest
;
tmp
=
((
ULONGLONG
)
b
->
data
[
bnum_idx
(
b
,
i
)]
*
mult
)
+
rest
;
rest
=
tmp
/
LIMB_MAX
;
b
->
data
[
BNUM_IDX
(
i
)]
=
tmp
%
LIMB_MAX
;
b
->
data
[
bnum_idx
(
b
,
i
)]
=
tmp
%
LIMB_MAX
;
if
(
i
==
b
->
b
&&
!
b
->
data
[
BNUM_IDX
(
i
)])
if
(
i
==
b
->
b
&&
!
b
->
data
[
bnum_idx
(
b
,
i
)])
b
->
b
++
;
}
if
(
rest
)
{
b
->
data
[
BNUM_IDX
(
b
->
e
)]
=
rest
;
b
->
data
[
bnum_idx
(
b
,
b
->
e
)]
=
rest
;
b
->
e
++
;
if
(
BNUM_IDX
(
b
->
b
)
==
BNUM_IDX
(
b
->
e
))
{
if
(
b
->
data
[
BNUM_IDX
(
b
->
b
)])
b
->
data
[
BNUM_IDX
(
b
->
b
+
1
)]
|=
1
;
if
(
bnum_idx
(
b
,
b
->
b
)
==
bnum_idx
(
b
,
b
->
e
))
{
if
(
b
->
data
[
bnum_idx
(
b
,
b
->
b
)])
b
->
data
[
bnum_idx
(
b
,
b
->
b
+
1
)]
|=
1
;
b
->
b
++
;
}
}
...
...
dlls/msvcrt/printf.h
View file @
74958219
...
...
@@ -577,11 +577,12 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
double
v
,
pf_flags
*
flags
,
MSVCRT__locale_t
locale
,
BOOL
three_digit_exp
)
{
int
e2
,
e10
=
0
,
round_pos
,
round_limb
,
radix_pos
,
first_limb_len
,
i
,
len
,
r
,
ret
;
BYTE
bnum_data
[
FIELD_OFFSET
(
struct
bnum
,
data
[
BNUM_PREC64
])];
struct
bnum
*
b
=
(
struct
bnum
*
)
bnum_data
;
APICHAR
buf
[
LIMB_DIGITS
+
1
];
BOOL
trim_tail
=
FALSE
;
pf_flags
f
;
int
limb_len
,
prec
;
struct
bnum
b
;
ULONGLONG
m
;
DWORD
l
;
...
...
@@ -594,33 +595,35 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
if
(
v
)
{
m
=
(
ULONGLONG
)
1
<<
(
MANT_BITS
-
1
);
m
|=
(
*
(
ULONGLONG
*
)
&
v
&
(((
ULONGLONG
)
1
<<
(
MANT_BITS
-
1
))
-
1
));
b
.
data
[
0
]
=
m
%
LIMB_MAX
;
b
.
data
[
1
]
=
m
/
LIMB_MAX
;
b
.
b
=
0
;
b
.
e
=
2
;
b
->
b
=
0
;
b
->
e
=
2
;
b
->
size
=
BNUM_PREC64
;
b
->
data
[
0
]
=
m
%
LIMB_MAX
;
b
->
data
[
1
]
=
m
/
LIMB_MAX
;
e2
-=
MANT_BITS
;
while
(
e2
>
0
)
{
int
shift
=
e2
>
29
?
29
:
e2
;
if
(
bnum_lshift
(
&
b
,
shift
))
e10
+=
LIMB_DIGITS
;
if
(
bnum_lshift
(
b
,
shift
))
e10
+=
LIMB_DIGITS
;
e2
-=
shift
;
}
while
(
e2
<
0
)
{
int
shift
=
-
e2
>
9
?
9
:
-
e2
;
if
(
bnum_rshift
(
&
b
,
shift
))
e10
-=
LIMB_DIGITS
;
if
(
bnum_rshift
(
b
,
shift
))
e10
-=
LIMB_DIGITS
;
e2
+=
shift
;
}
}
else
{
b
.
b
=
0
;
b
.
e
=
1
;
b
.
data
[
0
]
=
0
;
b
->
b
=
0
;
b
->
e
=
1
;
b
->
size
=
BNUM_PREC64
;
b
->
data
[
0
]
=
0
;
e10
=
-
LIMB_DIGITS
;
}
if
(
!
b
.
data
[
BNUM_IDX
(
b
.
e
-
1
)])
if
(
!
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)])
first_limb_len
=
1
;
else
first_limb_len
=
floor
(
log10
(
b
.
data
[
BNUM_IDX
(
b
.
e
-
1
)]))
+
1
;
first_limb_len
=
floor
(
log10
(
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]))
+
1
;
radix_pos
=
first_limb_len
+
LIMB_DIGITS
+
e10
;
round_pos
=
flags
->
Precision
;
...
...
@@ -629,11 +632,11 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
else
if
(
!
flags
->
Precision
||
flags
->
Format
==
'e'
||
flags
->
Format
==
'E'
)
round_pos
++
;
if
(
round_pos
<=
first_limb_len
)
round_limb
=
b
.
e
+
(
first_limb_len
-
round_pos
)
/
LIMB_DIGITS
-
1
;
round_limb
=
b
->
e
+
(
first_limb_len
-
round_pos
)
/
LIMB_DIGITS
-
1
;
else
round_limb
=
b
.
e
-
(
round_pos
-
first_limb_len
-
1
)
/
LIMB_DIGITS
-
2
;
round_limb
=
b
->
e
-
(
round_pos
-
first_limb_len
-
1
)
/
LIMB_DIGITS
-
2
;
if
(
b
.
b
<=
round_limb
&&
round_limb
<
b
.
e
)
{
if
(
b
->
b
<=
round_limb
&&
round_limb
<
b
->
e
)
{
BOOL
round_up
=
FALSE
;
if
(
round_pos
<=
first_limb_len
)
{
...
...
@@ -644,43 +647,43 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
}
if
(
round_pos
)
{
l
=
b
.
data
[
BNUM_IDX
(
round_limb
)]
%
p10s
[
round_pos
];
b
.
data
[
BNUM_IDX
(
round_limb
)]
-=
l
;
l
=
b
->
data
[
bnum_idx
(
b
,
round_limb
)]
%
p10s
[
round_pos
];
b
->
data
[
bnum_idx
(
b
,
round_limb
)]
-=
l
;
if
(
2
*
l
>=
p10s
[
round_pos
])
round_up
=
TRUE
;
}
else
if
(
round_limb
-
1
>=
b
.
b
)
{
if
(
2
*
b
.
data
[
BNUM_IDX
(
round_limb
-
1
)]
>=
LIMB_MAX
)
round_up
=
TRUE
;
}
else
if
(
round_limb
-
1
>=
b
->
b
)
{
if
(
2
*
b
->
data
[
bnum_idx
(
b
,
round_limb
-
1
)]
>=
LIMB_MAX
)
round_up
=
TRUE
;
}
b
.
b
=
round_limb
;
b
->
b
=
round_limb
;
if
(
round_up
)
{
b
.
data
[
BNUM_IDX
(
b
.
b
)]
+=
p10s
[
round_pos
];
for
(
i
=
b
.
b
;
i
<
b
.
e
;
i
++
)
{
if
(
b
.
data
[
BNUM_IDX
(
i
)]
<
LIMB_MAX
)
break
;
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
+=
p10s
[
round_pos
];
for
(
i
=
b
->
b
;
i
<
b
->
e
;
i
++
)
{
if
(
b
->
data
[
bnum_idx
(
b
,
i
)]
<
LIMB_MAX
)
break
;
b
.
data
[
BNUM_IDX
(
i
)]
-=
LIMB_MAX
;
if
(
i
+
1
<
b
.
e
)
b
.
data
[
BNUM_IDX
(
i
+
1
)]
++
;
else
b
.
data
[
BNUM_IDX
(
i
+
1
)]
=
1
;
b
->
data
[
bnum_idx
(
b
,
i
)]
-=
LIMB_MAX
;
if
(
i
+
1
<
b
->
e
)
b
->
data
[
bnum_idx
(
b
,
i
+
1
)]
++
;
else
b
->
data
[
bnum_idx
(
b
,
i
+
1
)]
=
1
;
}
if
(
i
==
b
.
e
-
1
)
{
if
(
!
b
.
data
[
BNUM_IDX
(
b
.
e
-
1
)])
if
(
i
==
b
->
e
-
1
)
{
if
(
!
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)])
i
=
1
;
else
i
=
floor
(
log10
(
b
.
data
[
BNUM_IDX
(
b
.
e
-
1
)]))
+
1
;
i
=
floor
(
log10
(
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]))
+
1
;
if
(
i
!=
first_limb_len
)
{
first_limb_len
=
i
;
radix_pos
++
;
}
}
else
if
(
i
==
b
.
e
)
{
}
else
if
(
i
==
b
->
e
)
{
first_limb_len
=
1
;
radix_pos
++
;
b
.
e
++
;
b
->
e
++
;
}
}
}
else
if
(
b
.
e
<=
round_limb
)
{
/* got 0 or 1 after rounding */
b
.
data
[
BNUM_IDX
(
round_limb
)]
=
b
.
e
==
round_limb
&&
b
.
data
[
BNUM_IDX
(
b
.
e
-
1
)]
>=
LIMB_MAX
/
2
;
b
.
b
=
round_limb
;
b
.
e
=
b
.
b
+
1
;
else
if
(
b
->
e
<=
round_limb
)
{
/* got 0 or 1 after rounding */
b
->
data
[
bnum_idx
(
b
,
round_limb
)]
=
b
->
e
==
round_limb
&&
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]
>=
LIMB_MAX
/
2
;
b
->
b
=
round_limb
;
b
->
e
=
b
->
b
+
1
;
first_limb_len
=
1
;
radix_pos
++
;
}
...
...
@@ -702,9 +705,9 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
}
if
(
trim_tail
&&
!
flags
->
Alternate
)
{
for
(
i
=
round_limb
;
flags
->
Precision
>
0
&&
i
<
b
.
e
;
i
++
)
{
if
(
i
>=
b
.
b
)
l
=
b
.
data
[
BNUM_IDX
(
i
)];
for
(
i
=
round_limb
;
flags
->
Precision
>
0
&&
i
<
b
->
e
;
i
++
)
{
if
(
i
>=
b
->
b
)
l
=
b
->
data
[
bnum_idx
(
b
,
i
)];
else
l
=
0
;
...
...
@@ -713,7 +716,7 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
r
=
radix_pos
+
flags
->
Precision
;
else
r
=
flags
->
Precision
+
1
;
r
=
first_limb_len
+
LIMB_DIGITS
*
(
b
.
e
-
1
-
b
.
b
)
-
r
;
r
=
first_limb_len
+
LIMB_DIGITS
*
(
b
->
e
-
1
-
b
->
b
)
-
r
;
r
%=
LIMB_DIGITS
;
if
(
r
<
0
)
r
+=
LIMB_DIGITS
;
l
/=
p10s
[
r
];
...
...
@@ -770,9 +773,9 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
}
limb_len
=
LIMB_DIGITS
;
for
(
i
=
b
.
e
-
1
;
radix_pos
>
0
&&
i
>=
b
.
b
;
i
--
)
{
limb_len
=
(
i
==
b
.
e
-
1
?
first_limb_len
:
LIMB_DIGITS
);
l
=
b
.
data
[
BNUM_IDX
(
i
)];
for
(
i
=
b
->
e
-
1
;
radix_pos
>
0
&&
i
>=
b
->
b
;
i
--
)
{
limb_len
=
(
i
==
b
->
e
-
1
?
first_limb_len
:
LIMB_DIGITS
);
l
=
b
->
data
[
bnum_idx
(
b
,
i
)];
if
(
limb_len
>
radix_pos
)
{
f
.
Precision
=
radix_pos
;
l
/=
p10s
[
limb_len
-
radix_pos
];
...
...
@@ -811,8 +814,8 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
ret
+=
r
;
}
for
(;
prec
>
0
&&
i
>=
b
.
b
;
i
--
)
{
l
=
b
.
data
[
BNUM_IDX
(
i
)];
for
(;
prec
>
0
&&
i
>=
b
->
b
;
i
--
)
{
l
=
b
->
data
[
bnum_idx
(
b
,
i
)];
if
(
limb_len
!=
LIMB_DIGITS
)
l
%=
p10s
[
limb_len
];
if
(
limb_len
>
prec
)
{
...
...
@@ -837,7 +840,7 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
ret
+=
r
;
}
}
else
{
l
=
b
.
data
[
BNUM_IDX
(
b
.
e
-
1
)];
l
=
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)];
l
/=
p10s
[
first_limb_len
-
1
];
buf
[
0
]
=
'0'
+
l
;
...
...
@@ -854,9 +857,9 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
prec
=
flags
->
Precision
;
limb_len
=
LIMB_DIGITS
;
for
(
i
=
b
.
e
-
1
;
prec
>
0
&&
i
>=
b
.
b
;
i
--
)
{
l
=
b
.
data
[
BNUM_IDX
(
i
)];
if
(
i
==
b
.
e
-
1
)
{
for
(
i
=
b
->
e
-
1
;
prec
>
0
&&
i
>=
b
->
b
;
i
--
)
{
l
=
b
->
data
[
bnum_idx
(
b
,
i
)];
if
(
i
==
b
->
e
-
1
)
{
limb_len
=
first_limb_len
-
1
;
l
%=
p10s
[
limb_len
];
}
...
...
dlls/msvcrt/string.c
View file @
74958219
...
...
@@ -581,10 +581,11 @@ double parse_double(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *ctx),
int
matched
=
0
;
#endif
BOOL
found_digit
=
FALSE
,
found_dp
=
FALSE
,
found_sign
=
FALSE
;
BYTE
bnum_data
[
FIELD_OFFSET
(
struct
bnum
,
data
[
BNUM_PREC64
])];
int
e2
=
0
,
dp
=
0
,
sign
=
1
,
off
,
limb_digits
=
0
,
i
;
struct
bnum
*
b
=
(
struct
bnum
*
)
bnum_data
;
enum
round
round
=
ROUND_ZERO
;
MSVCRT_wchar_t
nch
;
struct
bnum
b
;
nch
=
get
(
ctx
);
if
(
nch
==
'-'
)
{
...
...
@@ -637,27 +638,28 @@ double parse_double(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *ctx),
nch
=
get
(
ctx
);
}
b
.
data
[
0
]
=
0
;
b
.
b
=
0
;
b
.
e
=
1
;
b
->
b
=
0
;
b
->
e
=
1
;
b
->
size
=
BNUM_PREC64
;
b
->
data
[
0
]
=
0
;
while
(
nch
>=
'0'
&&
nch
<=
'9'
)
{
found_digit
=
TRUE
;
if
(
limb_digits
==
LIMB_DIGITS
)
{
if
(
BNUM_IDX
(
b
.
b
-
1
)
==
BNUM_IDX
(
b
.
e
))
break
;
if
(
bnum_idx
(
b
,
b
->
b
-
1
)
==
bnum_idx
(
b
,
b
->
e
))
break
;
else
{
b
.
b
--
;
b
.
data
[
BNUM_IDX
(
b
.
b
)]
=
0
;
b
->
b
--
;
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
=
0
;
limb_digits
=
0
;
}
}
b
.
data
[
BNUM_IDX
(
b
.
b
)]
=
b
.
data
[
BNUM_IDX
(
b
.
b
)]
*
10
+
nch
-
'0'
;
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
=
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
*
10
+
nch
-
'0'
;
limb_digits
++
;
nch
=
get
(
ctx
);
dp
++
;
}
while
(
nch
>=
'0'
&&
nch
<=
'9'
)
{
if
(
nch
!=
'0'
)
b
.
data
[
BNUM_IDX
(
b
.
b
)]
|=
1
;
if
(
nch
!=
'0'
)
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
|=
1
;
nch
=
get
(
ctx
);
dp
++
;
}
...
...
@@ -668,7 +670,7 @@ double parse_double(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *ctx),
}
/* skip leading '0' */
if
(
nch
==
'0'
&&
!
limb_digits
&&
!
b
.
b
)
{
if
(
nch
==
'0'
&&
!
limb_digits
&&
!
b
->
b
)
{
found_digit
=
TRUE
;
while
(
nch
==
'0'
)
{
nch
=
get
(
ctx
);
...
...
@@ -679,20 +681,20 @@ double parse_double(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *ctx),
while
(
nch
>=
'0'
&&
nch
<=
'9'
)
{
found_digit
=
TRUE
;
if
(
limb_digits
==
LIMB_DIGITS
)
{
if
(
BNUM_IDX
(
b
.
b
-
1
)
==
BNUM_IDX
(
b
.
e
))
break
;
if
(
bnum_idx
(
b
,
b
->
b
-
1
)
==
bnum_idx
(
b
,
b
->
e
))
break
;
else
{
b
.
b
--
;
b
.
data
[
BNUM_IDX
(
b
.
b
)]
=
0
;
b
->
b
--
;
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
=
0
;
limb_digits
=
0
;
}
}
b
.
data
[
BNUM_IDX
(
b
.
b
)]
=
b
.
data
[
BNUM_IDX
(
b
.
b
)]
*
10
+
nch
-
'0'
;
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
=
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
*
10
+
nch
-
'0'
;
limb_digits
++
;
nch
=
get
(
ctx
);
}
while
(
nch
>=
'0'
&&
nch
<=
'9'
)
{
if
(
nch
!=
'0'
)
b
.
data
[
BNUM_IDX
(
b
.
b
)]
|=
1
;
if
(
nch
!=
'0'
)
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
|=
1
;
nch
=
get
(
ctx
);
}
...
...
@@ -746,23 +748,23 @@ double parse_double(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *ctx),
unget
(
ctx
);
}
if
(
!
b
.
data
[
BNUM_IDX
(
b
.
e
-
1
)])
return
make_double
(
sign
,
0
,
0
,
ROUND_ZERO
,
err
);
if
(
!
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)])
return
make_double
(
sign
,
0
,
0
,
ROUND_ZERO
,
err
);
/* Fill last limb with 0 if needed */
if
(
b
.
b
+
1
!=
b
.
e
)
{
if
(
b
->
b
+
1
!=
b
->
e
)
{
for
(;
limb_digits
!=
LIMB_DIGITS
;
limb_digits
++
)
b
.
data
[
BNUM_IDX
(
b
.
b
)]
*=
10
;
b
->
data
[
bnum_idx
(
b
,
b
->
b
)]
*=
10
;
}
for
(;
BNUM_IDX
(
b
.
b
)
<
BNUM_IDX
(
b
.
e
);
b
.
b
++
)
{
if
(
b
.
data
[
BNUM_IDX
(
b
.
b
)])
break
;
for
(;
bnum_idx
(
b
,
b
->
b
)
<
bnum_idx
(
b
,
b
->
e
);
b
->
b
++
)
{
if
(
b
->
data
[
bnum_idx
(
b
,
b
->
b
)])
break
;
}
/* move decimal point to limb boundary */
if
(
limb_digits
==
dp
&&
b
.
b
==
b
.
e
-
1
)
return
make_double
(
sign
,
0
,
b
.
data
[
BNUM_IDX
(
b
.
e
-
1
)],
ROUND_ZERO
,
err
);
if
(
limb_digits
==
dp
&&
b
->
b
==
b
->
e
-
1
)
return
make_double
(
sign
,
0
,
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)],
ROUND_ZERO
,
err
);
off
=
(
dp
-
limb_digits
)
%
LIMB_DIGITS
;
if
(
off
<
0
)
off
+=
LIMB_DIGITS
;
if
(
off
)
bnum_mult
(
&
b
,
p10s
[
off
]);
if
(
off
)
bnum_mult
(
b
,
p10s
[
off
]);
if
(
dp
-
1
>
MSVCRT_DBL_MAX_10_EXP
)
return
make_double
(
sign
,
INT_MAX
,
1
,
ROUND_ZERO
,
err
);
...
...
@@ -772,27 +774,27 @@ double parse_double(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *ctx),
return
make_double
(
sign
,
INT_MIN
,
1
,
ROUND_ZERO
,
err
);
while
(
dp
>
2
*
LIMB_DIGITS
)
{
if
(
bnum_rshift
(
&
b
,
9
))
dp
-=
LIMB_DIGITS
;
if
(
bnum_rshift
(
b
,
9
))
dp
-=
LIMB_DIGITS
;
e2
+=
9
;
}
while
(
dp
<=
LIMB_DIGITS
)
{
if
(
bnum_lshift
(
&
b
,
29
))
dp
+=
LIMB_DIGITS
;
if
(
bnum_lshift
(
b
,
29
))
dp
+=
LIMB_DIGITS
;
e2
-=
29
;
}
while
(
b
.
data
[
BNUM_IDX
(
b
.
e
-
1
)]
<
LIMB_MAX
/
10
)
{
bnum_lshift
(
&
b
,
1
);
while
(
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]
<
LIMB_MAX
/
10
)
{
bnum_lshift
(
b
,
1
);
e2
--
;
}
/* Check if fractional part is non-zero */
/* Caution: it's only correct because bnum_to_mant returns more than 53 bits */
for
(
i
=
b
.
e
-
3
;
i
>=
b
.
b
;
i
--
)
{
if
(
!
b
.
data
[
BNUM_IDX
(
b
.
b
)])
continue
;
for
(
i
=
b
->
e
-
3
;
i
>=
b
->
b
;
i
--
)
{
if
(
!
b
->
data
[
bnum_idx
(
b
,
b
->
b
)])
continue
;
round
=
ROUND_DOWN
;
break
;
}
return
make_double
(
sign
,
e2
,
bnum_to_mant
(
&
b
),
round
,
err
);
return
make_double
(
sign
,
e2
,
bnum_to_mant
(
b
),
round
,
err
);
}
static
MSVCRT_wchar_t
strtod_str_get
(
void
*
ctx
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment