summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2014-09-24 07:29:09 -0400
committerJarkko Hietaniemi <jhi@iki.fi>2014-09-24 19:14:19 -0400
commita13f4dff39a8e5b2dfd82fe8fb21125753c7022b (patch)
treefd4451ef38dcb651bba35e7d8285a814cfade6f5 /sv.c
parent5bf8b78e07edcdb636cf0f1a8c1e9e97f2ce2f53 (diff)
downloadperl-a13f4dff39a8e5b2dfd82fe8fb21125753c7022b.tar.gz
If we already know it's infnan, no need to Atof again.
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/sv.c b/sv.c
index 1a2f071466..ffa9c01ad4 100644
--- a/sv.c
+++ b/sv.c
@@ -2063,6 +2063,30 @@ S_sv_2iuv_non_preserve(pTHX_ SV *const sv
}
#endif /* !NV_PRESERVES_UV*/
+/* If numtype is infnan, set the NV of the sv accordingly.
+ * If numtype is anything else, set the NV using Atof(PV). */
+static void
+S_sv_setnv(SV* sv, int numtype)
+{
+ bool pok = SvPOK(sv);
+ if ((numtype & IS_NUMBER_INFINITY)) {
+ SvNV_set(sv, (numtype & IS_NUMBER_NEG) ? -NV_INF : NV_INF);
+ SvNOK_only(sv);
+ if (pok)
+ SvPOK_on(sv);
+ }
+ else if ((numtype & IS_NUMBER_NAN)) {
+ SvNV_set(sv, NV_NAN);
+ SvNOK_only(sv);
+ if (pok)
+ SvPOK_on(sv);
+ }
+ else if (pok)
+ SvNV_set(sv, Atof(SvPVX_const(sv)));
+ else
+ return;
+}
+
STATIC bool
S_sv_2iuv_common(pTHX_ SV *const sv)
{
@@ -2176,6 +2200,11 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
} else if (SvTYPE(sv) < SVt_PVNV)
sv_upgrade(sv, SVt_PVNV);
+ if ((numtype & (IS_NUMBER_INFINITY | IS_NUMBER_NAN))) {
+ S_sv_setnv(sv, numtype);
+ return FALSE;
+ }
+
/* If NVs preserve UVs then we only use the UV value if we know that
we aren't going to call atof() below. If NVs don't preserve UVs
then the value returned may have more precision than atof() will
@@ -2221,7 +2250,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
if ((numtype & (IS_NUMBER_IN_UV | IS_NUMBER_NOT_INT))
!= IS_NUMBER_IN_UV) {
/* It wasn't an (integer that doesn't overflow the UV). */
- SvNV_set(sv, Atof(SvPVX_const(sv)));
+ S_sv_setnv(sv, numtype);
if (! numtype && ckWARN(WARN_NUMERIC))
not_a_number(sv);
@@ -2623,12 +2652,7 @@ Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags)
/* It's definitely an integer */
SvNV_set(sv, (numtype & IS_NUMBER_NEG) ? -(NV)value : (NV)value);
} else {
- if ((numtype & IS_NUMBER_INFINITY))
- SvNV_set(sv, (numtype & IS_NUMBER_NEG) ? -NV_INF : NV_INF);
- else if ((numtype & IS_NUMBER_NAN))
- SvNV_set(sv, NV_NAN);
- else
- SvNV_set(sv, Atof(SvPVX_const(sv)));
+ S_sv_setnv(sv, numtype);
}
if (numtype)
SvNOK_on(sv);