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
8fc48e8b
Commit
8fc48e8b
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: Create 64-bit mantissa in fpnum_parse.
Signed-off-by:
Piotr Caban
<
piotr@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
45001578
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
28 additions
and
14 deletions
+28
-14
bnum.h
dlls/msvcrt/bnum.h
+2
-9
string.c
dlls/msvcrt/string.c
+26
-5
No files found.
dlls/msvcrt/bnum.h
View file @
8fc48e8b
...
...
@@ -28,7 +28,8 @@ static const int p10s[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
#define LIMB_MAX 1000000000
/* 10^9 */
#define BNUM_PREC64 128
/* data size needed to store 64-bit double */
/* bnum represents real number with fixed decimal point (after 2 limbs) */
/* bnum represents real number with fixed decimal point */
struct
bnum
{
int
b
;
/* least significant digit position */
int
e
;
/* most significant digit position + 1 */
...
...
@@ -41,14 +42,6 @@ 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
,
b
->
e
-
1
)]
*
LIMB_MAX
;
if
(
b
->
b
!=
b
->
e
-
1
)
ret
+=
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
2
)];
return
ret
;
}
/* Returns TRUE if new most significant limb was added */
static
inline
BOOL
bnum_lshift
(
struct
bnum
*
b
,
int
shift
)
{
...
...
dlls/msvcrt/string.c
View file @
8fc48e8b
...
...
@@ -597,6 +597,21 @@ static struct fpnum fpnum_parse16(MSVCRT_wchar_t get(void *ctx), void unget(void
}
#endif
/* Converts first 3 limbs to ULONGLONG */
/* Return FALSE on overflow */
static
inline
BOOL
bnum_to_mant
(
struct
bnum
*
b
,
ULONGLONG
*
m
)
{
if
(
MSVCRT_UI64_MAX
/
LIMB_MAX
/
LIMB_MAX
<
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)])
return
FALSE
;
*
m
=
(
ULONGLONG
)
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]
*
LIMB_MAX
*
LIMB_MAX
;
if
(
b
->
b
==
b
->
e
-
1
)
return
TRUE
;
if
(
MSVCRT_UI64_MAX
-
*
m
<
(
ULONGLONG
)
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
2
)]
*
LIMB_MAX
)
return
FALSE
;
*
m
+=
(
ULONGLONG
)
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
2
)]
*
LIMB_MAX
;
if
(
b
->
b
==
b
->
e
-
2
)
return
TRUE
;
if
(
MSVCRT_UI64_MAX
-
*
m
<
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
3
)])
return
FALSE
;
*
m
+=
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
3
)];
return
TRUE
;
}
struct
fpnum
fpnum_parse
(
MSVCRT_wchar_t
(
*
get
)(
void
*
ctx
),
void
(
*
unget
)(
void
*
ctx
),
void
*
ctx
,
MSVCRT_pthreadlocinfo
locinfo
)
{
...
...
@@ -612,6 +627,7 @@ struct fpnum fpnum_parse(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *c
struct
bnum
*
b
=
(
struct
bnum
*
)
bnum_data
;
enum
fpmod
round
=
FP_ROUND_ZERO
;
MSVCRT_wchar_t
nch
;
ULONGLONG
m
;
nch
=
get
(
ctx
);
if
(
nch
==
'-'
)
{
...
...
@@ -797,28 +813,33 @@ struct fpnum fpnum_parse(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *c
if
(
dp
-
1
<
MSVCRT_DBL_MIN_10_EXP
-
MSVCRT_DBL_DIG
-
18
)
return
fpnum
(
sign
,
INT_MIN
,
1
,
FP_ROUND_ZERO
);
while
(
dp
>
2
*
LIMB_DIGITS
)
{
while
(
dp
>
3
*
LIMB_DIGITS
)
{
if
(
bnum_rshift
(
b
,
9
))
dp
-=
LIMB_DIGITS
;
e2
+=
9
;
}
while
(
dp
<=
LIMB_DIGITS
)
{
while
(
dp
<=
2
*
LIMB_DIGITS
)
{
if
(
bnum_lshift
(
b
,
29
))
dp
+=
LIMB_DIGITS
;
e2
-=
29
;
}
while
(
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]
<
LIMB_MAX
/
10
)
{
/* Make sure most significant mantissa bit will be set */
while
(
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]
<=
9
)
{
bnum_lshift
(
b
,
1
);
e2
--
;
}
while
(
!
bnum_to_mant
(
b
,
&
m
))
{
bnum_rshift
(
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
--
)
{
for
(
i
=
b
->
e
-
4
;
i
>=
b
->
b
;
i
--
)
{
if
(
!
b
->
data
[
bnum_idx
(
b
,
b
->
b
)])
continue
;
round
=
FP_ROUND_DOWN
;
break
;
}
return
fpnum
(
sign
,
e2
,
bnum_to_mant
(
b
)
,
round
);
return
fpnum
(
sign
,
e2
,
m
,
round
);
}
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