From a6f33e330bfea8b112b2c9d89a4616e5fe10bd6f Mon Sep 17 00:00:00 2001 From: stijn Date: Sun, 17 May 2020 12:29:25 +0200 Subject: [PATCH 1/3] py/modmath: Workaround msvc bugs in atan2, fmod and modf. Older implementations deal with infinity/negative zero incorrectly. Add fixes and tests. --- ports/windows/mpconfigport.h | 8 ++++++++ py/modmath.c | 27 ++++++++++++++++++++++++++- py/mpconfig.h | 15 +++++++++++++++ tests/float/math_domain.py | 4 ++-- 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index 84c196e11fa9c..fa09dda7527e0 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -227,6 +227,14 @@ extern const struct _mp_obj_module_t mp_module_time; #define MP_SSIZE_MAX _I32_MAX #endif +// VC++ 12.0 fixes +#if (_MSC_VER <= 1800) +#define MICROPY_PY_MATH_ATAN2_FIX_INFNAN (1) +#define MICROPY_PY_MATH_FMOD_FIX_INFNAN (1) +#ifdef _WIN64 +#define MICROPY_PY_MATH_MODF_FIX_NEGZERO (1) +#endif +#endif // CL specific definitions diff --git a/py/modmath.c b/py/modmath.c index 5ff892ba112c8..b312eeb3d2c01 100644 --- a/py/modmath.c +++ b/py/modmath.c @@ -34,6 +34,8 @@ // M_PI is not part of the math.h standard and may not be defined // And by defining our own we can ensure it uses the correct const format. #define MP_PI MICROPY_FLOAT_CONST(3.14159265358979323846) +#define MP_PI_4 MICROPY_FLOAT_CONST(0.78539816339744830962) +#define MP_3_PI_4 MICROPY_FLOAT_CONST(2.35619449019234492885) STATIC NORETURN void math_error(void) { mp_raise_ValueError(MP_ERROR_TEXT("math domain error")); @@ -132,7 +134,17 @@ MATH_FUN_1(asin, asin) // atan(x) MATH_FUN_1(atan, atan) // atan2(y, x) +#if MICROPY_PY_MATH_ATAN2_FIX_INFNAN +mp_float_t atan2_func(mp_float_t x, mp_float_t y) { + if (isinf(x) && isinf(y)) { + return copysign(y < 0 ? MP_3_PI_4 : MP_PI_4, x); + } + return atan2(x, y); +} +MATH_FUN_2(atan2, atan2_func) +#else MATH_FUN_2(atan2, atan2) +#endif // ceil(x) MATH_FUN_1_TO_INT(ceil, ceil) // copysign(x, y) @@ -148,7 +160,14 @@ MATH_FUN_1(fabs, fabs_func) // floor(x) MATH_FUN_1_TO_INT(floor, floor) // TODO: delegate to x.__floor__() if x is not a float // fmod(x, y) +#if MICROPY_PY_MATH_FMOD_FIX_INFNAN +mp_float_t fmod_func(mp_float_t x, mp_float_t y) { + return (!isinf(x) && isinf(y)) ? x : fmod(x, y); +} +MATH_FUN_2(fmod, fmod_func) +#else MATH_FUN_2(fmod, fmod) +#endif // isfinite(x) MATH_FUN_1_TO_BOOL(isfinite, isfinite) // isinf(x) @@ -246,7 +265,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_frexp_obj, mp_math_frexp); // modf(x) STATIC mp_obj_t mp_math_modf(mp_obj_t x_obj) { mp_float_t int_part = 0.0; - mp_float_t fractional_part = MICROPY_FLOAT_C_FUN(modf)(mp_obj_get_float(x_obj), &int_part); + mp_float_t x = mp_obj_get_float(x_obj); + mp_float_t fractional_part = MICROPY_FLOAT_C_FUN(modf)(x, &int_part); + #if MICROPY_PY_MATH_MODF_FIX_NEGZERO + if (fractional_part == MICROPY_FLOAT_CONST(0.0)) { + fractional_part = copysign(fractional_part, x); + } + #endif mp_obj_t tuple[2]; tuple[0] = mp_obj_new_float(fractional_part); tuple[1] = mp_obj_new_float(int_part); diff --git a/py/mpconfig.h b/py/mpconfig.h index f2b3af1f2a314..27df3f483a0e1 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1128,6 +1128,21 @@ typedef double mp_float_t; #define MICROPY_PY_MATH_ISCLOSE (0) #endif +// Whether to provide fix for atan2 Inf handling. +#ifndef MICROPY_PY_MATH_ATAN2_FIX_INFNAN +#define MICROPY_PY_MATH_ATAN2_FIX_INFNAN (0) +#endif + +// Whether to provide fix for fmod Inf handling. +#ifndef MICROPY_PY_MATH_FMOD_FIX_INFNAN +#define MICROPY_PY_MATH_FMOD_FIX_INFNAN (0) +#endif + +// Whether to provide fix for modf negative zero handling. +#ifndef MICROPY_PY_MATH_MODF_FIX_NEGZERO +#define MICROPY_PY_MATH_MODF_FIX_NEGZERO (0) +#endif + // Whether to provide "cmath" module #ifndef MICROPY_PY_CMATH #define MICROPY_PY_CMATH (0) diff --git a/tests/float/math_domain.py b/tests/float/math_domain.py index 2d4670f75dd48..e63628cf5078a 100644 --- a/tests/float/math_domain.py +++ b/tests/float/math_domain.py @@ -39,8 +39,8 @@ # double argument functions for name, f, args in ( ("pow", math.pow, ((0, 2), (-1, 2), (0, -1), (-1, 2.3))), - ("fmod", math.fmod, ((1.2, inf), (1.2, 0), (inf, 1.2))), - ("atan2", math.atan2, ((0, 0),)), + ("fmod", math.fmod, ((1.2, inf), (1.2, -inf), (1.2, 0), (inf, 1.2))), + ("atan2", math.atan2, ((0, 0), (-inf, inf), (-inf, -inf), (inf, -inf))), ("copysign", math.copysign, ()), ): for x in args + ((0, inf), (inf, 0), (inf, inf), (inf, nan), (nan, inf), (nan, nan)): From ab9e8bf4ab8f5e985c6d886b7796cf4470be6a57 Mon Sep 17 00:00:00 2001 From: stijn Date: Sun, 17 May 2020 10:57:51 +0200 Subject: [PATCH 2/3] py/ringbuf: Fix compilation with msvc. Older versions do not have inline so fetch definition from mpconfigport.h. --- py/ringbuf.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py/ringbuf.h b/py/ringbuf.h index 4d316d961b2b5..293e418306051 100644 --- a/py/ringbuf.h +++ b/py/ringbuf.h @@ -29,6 +29,10 @@ #include #include +#ifdef _MSC_VER +#include "py/mpconfig.h" // For inline. +#endif + typedef struct _ringbuf_t { uint8_t *buf; uint16_t size; From 56b30eb9b3f022a6b4291723258c44008b3f5432 Mon Sep 17 00:00:00 2001 From: stijn Date: Sun, 17 May 2020 09:39:59 +0200 Subject: [PATCH 3/3] windows: Make appveyor.yml self-contained. Add configuration which otherwise has to be set via the UI so the file is more self-contained, and remove configuration which is not needed because it's the same as the default. The major change here is that for a while now Appveyor has been using Visual Studio 2015 by default while we still want to support 2013. --- ports/windows/.appveyor.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/ports/windows/.appveyor.yml b/ports/windows/.appveyor.yml index 2e0dbdea5d116..2965543b05942 100644 --- a/ports/windows/.appveyor.yml +++ b/ports/windows/.appveyor.yml @@ -1,3 +1,7 @@ +image: Visual Studio 2013 +clone_depth: 1 +skip_tags: true + environment: # Python version used MICROPY_CPYTHON3: c:/python34/python.exe @@ -71,10 +75,3 @@ after_test: if ($LASTEXITCODE -ne 0) { throw "$env:MSYSTEM mpy-cross tests exited with code $LASTEXITCODE" } - -skip_tags: true - -deploy: off - -nuget: - disable_publish_on_pr: true pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy